Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

FairPlay HLS Downloaded Asset Fails to Play on First Attempt When Offline, Works on Retry

Hello,

We're seeing an intermittent issue when playing back FairPlay-protected HLS downloads while the device is offline.

Assets are downloaded using AVAggregateAssetDownloadTask with FairPlay protection.

After download, asset.assetCache.isPlayableOffline == true.

On first playback attempt (offline), ~8% of downloads fail.

Retrying playback always works. We recreate the asset and player on each attempt.

During the playback setup, we try to load variants via:

try await asset.load(.variants)

This call sometimes fails with:

Error Domain=NSURLErrorDomain Code=-1009 “The Internet connection appears to be offline.” UserInfo={NSUnderlyingError=0x105654a00 {Error Domain=NSURLErrorDomain Code=-1009 “The Internet connection appears to be offline.” UserInfo={NSDescription=The Internet connection appears to be offline.}}, NSErrorFailingURLStringKey=file:///private/var/mobile/Containers/Data/Application/2DDF9D7C-9197-46BE-8690-C23EE75C9E90/Library/com.apple.UserManagedAssets.XVvqfh/Baggage_9DD4E2D3F9C0E68F.movpkg/, NSErrorFailingURLKey=file:///private/var/mobile/Containers/Data/Application/2DDF9D7C-9197-46BE-8690-C23EE75C9E90/Library/com.apple.UserManagedAssets.XVvqfh/Baggage_9DD4E2D3F9C0E68F.movpkg/, NSURL=file:///private/var/mobile/Containers/Data/Application/2DDF9D7C-9197-46BE-8690-C23EE75C9E90/Library/com.apple.UserManagedAssets.XVvqfh/Baggage_9DD4E2D3F9C0E68F.movpkg/, AVErrorFailedDependenciesKey=(
  “assetProperty_HLSAlternates”
), NSLocalizedDescription=The Internet connection appears to be offline.}

This variant load is used to determine available audio tracks, check for Dolby support, and apply user language preferences.

After this step, the AVPlayerItem also fails via Combine’s publisher for .status.

However, retrying the entire process immediately after (same offline conditions, same asset path, new AVURLAsset) results in successful playback.

Assets are represented using the following class:

public class DownloadedAsset: AVURLAsset {
    public let id: String
    public let localFileUrl: URL
    public let fairplayLicenseUrlString: String?
    public let drmToken: String?

    var isProtected: Bool {
        return fairplayLicenseUrlString != nil
    }

    public init(id: String,
                localFileUrl: URL,
                fairplayLicenseUrlString: String?,
                drmToken: String?) {
        self.id = id
        self.localFileUrl = localFileUrl
        self.fairplayLicenseUrlString = fairplayLicenseUrlString
        self.drmToken = drmToken
        super.init(url: localFileUrl, options: nil)
    }
}

We use user-selected quality levels to control bitrate and multichannel (e.g. Dolby 5.1) downloads:

let downloadQuality = UserDefaults.standard.downloadVideoQuality
let bitrate: Int
let shouldDownloadMultichannelTracks: Bool

switch downloadQuality {
case .dataSaver:
    shouldDownloadMultichannelTracks = false
    bitrate = 596564
case .standard:
    shouldDownloadMultichannelTracks = false
    bitrate = 1503844
case .best:
    shouldDownloadMultichannelTracks = true
    bitrate = 7038970
}

var selections = multichannelIdentifiedMediaSelections
if !shouldDownloadMultichannelTracks {
    selections = selections.filter { !$0.isMultichannel }
}

let task = session.aggregateAssetDownloadTask(
    with: asset,
    mediaSelections: selections.map { $0.mediaSelection },
    assetTitle: title,
    assetArtworkData: nil,
    options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: bitrate]
)

Seen on devices running iOS 16, iOS 17, and iOS 18.

What could cause the initial failure of an otherwise valid, offline-ready FairPlay HLS asset?

Could .load(.variants) internally trigger a failed network resolution, even when offline?

Is there an internal caching or initialization behavior in AVFoundation that might explain why the second attempt works?

Any guidance would be appreciated.

It's difficult to tell without a full sysdiagnose log. Perhaps if you file a Feedback report and attach a sysdiagnose the engineering team will be able to tell you what's going on (assuming it's not a bug).

FairPlay HLS Downloaded Asset Fails to Play on First Attempt When Offline, Works on Retry
 
 
Q