AVAssetDownloadConfiguration does not download supplemental tracks on iOS 16

We're downloading HLS content for offline playback using AVAssetDownloadConfiguration. It's critical for our app that all subtitle tracks are downloaded together with the video, so users can watch any subtitle and audio option while offline. On iOS 16, not all tracks are downloaded, and when the user goes offline, playback fails with NSURLErrorNotConnectedToInternet (error -1009) because AVFoundation tries to fetch the missing subtitle segments over the network.

On iOS 17 and later, everything works as expected — all subtitle and audio tracks are downloaded. However, on iOS 16 we observe two issues:

First issue: Supplemental tracks are not downloaded on iOS 16 (device)

Only the default audio track is downloaded. All non-default supplemental tracks — both subtitles and additional audio tracks — exhibit the same problem:

  • Some supplemental tracks listed in the manifest don't even get a directory created in the .movpkg package

  • Some supplemental tracks do get a directory created, but it contains only StreamInfoBoot.xml and StreamInfoRoot.xml — no actual segment data (.frag files) is downloaded. The StreamInfoBoot.xml for these directories shows <Complete>NO</Complete>, <PeakBandwidth>0</PeakBandwidth>, and <MediaBytesStored>0</MediaBytesStored>, with <Type>Supplemental</Type>

  • Additionally, a Manifest.m3u8 stream directory is created with Complete=NO and no segment data.

On iOS 17+ devices, all supplemental track directories are created and all contain segment data.

Second issue: Downloads fail entirely on iOS 16 Simulator

We receive the following error:

Error Domain=NSURLErrorDomain Code=-16090
UserInfo={
    NSLocalizedDescription=The operation could not be completed,
    _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundAVAssetDownloadTask <DEC0D555-6C05-416C-91B8-F490F5A29046>.<3>,
    _NSURLErrorRelatedURLSessionTaskErrorKey=(
        "BackgroundAVAssetDownloadTask <DEC0D555-6C05-416C-91B8-F490F5A29046>.<3>"
    ),
    NSLocalizedFailureReason=An unknown error occurred (-16090)
}

On iOS 17+ Simulators, downloads work without issues.

Our setup:

let urlAsset = AVURLAsset(url: manifestURL)

let preferredMediaSelection = try await urlAsset.load(.allMediaSelections)

let config = AVAssetDownloadConfiguration(asset: urlAsset, title: title)
config.primaryContentConfiguration.mediaSelections = preferredMediaSelection

let task = assetDownloadURLSession.makeAssetDownloadTask(downloadConfiguration: config)
task.resume()

Example HLS manifest:

#EXTM3U
#EXT-X-VERSION:7

#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="French",LANGUAGE="fr",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,URI="s_25/stream.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="French (forced)",LANGUAGE="fr-x-cc",DEFAULT=NO,AUTOSELECT=YES,FORCED=YES,URI="s_31/stream.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",LANGUAGE="en",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,URI="s_37/stream.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Kazakh",LANGUAGE="kk",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,URI="s_43/stream.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Uzbek",LANGUAGE="uz",DEFAULT=NO,AUTOSELECT=YES,FORCED=NO,URI="s_49/stream.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aud_ec3",NAME="French 5.1",LANGUAGE="fr",DEFAULT=YES,AUTOSELECT=YES,CHANNELS="6",URI="a_18/stream.m3u8"

#EXT-X-STREAM-INF:AUDIO="aud_ec3",SUBTITLES="subs",BANDWIDTH=1931408,VIDEO-RANGE=SDR,CODECS="hvc1.1.6.L90.90,ec-3",RESOLUTION=1024x428,FRAME-RATE=25,HDCP-LEVEL=NONE
v_6/stream.m3u8
#EXT-X-SESSION-KEY:METHOD=SAMPLE-AES,URI="skd://XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"

Questions:

  1. What is the correct way to make sure all supplemental tracks (subtitles, non-default audio) are actually downloaded on an iOS 16 real device? We pass asset.load(.allMediaSelections) to primaryContentConfiguration.mediaSelections — is there a different configuration, or should we use auxiliaryContentConfigurations, or something else entirely?
  2. Is there any way to make asset downloads work on the iOS 16 Simulator at all? We always get NSURLErrorDomain error -16090, while iOS 17+ Simulators work fine.
  3. If the supplemental tracks download bug on iOS 16 cannot be fixed or worked around from the app side, do you have any recommended approach for handling incomplete .movpkg packages at offline playback time?

For the manifest shown above, here is what we observe when downloading on an iOS 16 device vs an iOS 17+ device:

iOS 16 device — downloaded .movpkg contents:

  • v_6 (video) — Complete=YES, 1532 segment files. Downloaded correctly.

  • a_18 (audio, default) — Complete=YES, 1532 segment files. Downloaded correctly.

  • s_25 (subtitle) — directory not created in the .movpkg package.

  • s_31 (subtitle) — directory created, but contains only StreamInfoBoot.xml with Complete=NO, PeakBandwidth=0, MediaBytesStored=0. No segment files.

  • s_37 (subtitle) — directory not created.

  • s_43 (subtitle) — directory not created.

  • s_49 (subtitle) — directory not created.

Only 1 out of 5 subtitle tracks got a directory created, and it contains no segment data. We tested the same content on a second iOS 16 device — there, 2 out of 5 subtitle tracks got empty directories (different tracks). The behavior is inconsistent across devices.

When the user goes offline, AVFoundation sees the incomplete subtitle stream in the package and attempts to fetch the missing segments over the network, resulting in NSURLErrorNotConnectedToInternet (error -1009).

iOS 17+ device:

All 5 subtitle track directories are created and all contain segment data. Offline playback works without issues.

AVAssetDownloadConfiguration does not download supplemental tracks on iOS 16
 
 
Q