google/ExoPlayer · error · IllegalStateException
Multiple IMA server side ad insertion sources not supported.
Error message
Multiple IMA server side ad insertion sources not supported.
What it means
assertSingleInstanceInPlaylist walks the player's playlist and counts items whose URI uses the imasky:// scheme with the IMA authority; if more than one is found it throws IllegalStateException. Server-side ad insertion through this extension is architected around a single active SSAI stream per player, so a second such item is rejected rather than playing incorrectly.
Source
Thrown at extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaServerSideAdInsertionMediaSource.java:1370
AdOverlayInfo overlayInfo = adViewProvider.getAdOverlayInfos().get(i);
container.registerFriendlyObstruction(
imaSdkFactory.createFriendlyObstruction(
overlayInfo.view,
ImaUtil.getFriendlyObstructionPurpose(overlayInfo.purpose),
overlayInfo.reasonDetail != null ? overlayInfo.reasonDetail : "Unknown reason"));
}
}
private static void assertSingleInstanceInPlaylist(Player player) {
int counter = 0;
for (int i = 0; i < player.getMediaItemCount(); i++) {
MediaItem mediaItem = player.getMediaItemAt(i);
if (mediaItem.localConfiguration != null
&& C.SSAI_SCHEME.equals(mediaItem.localConfiguration.uri.getScheme())
&& ImaServerSideAdInsertionUriBuilder.IMA_AUTHORITY.equals(
mediaItem.localConfiguration.uri.getAuthority())) {
if (++counter > 1) {
throw new IllegalStateException(
"Multiple IMA server side ad insertion sources not supported.");
}
}
}
}
private class VodAdEventListener implements AdEventListener {
@Override
public void onAdEvent(AdEvent event) {
AdPlaybackState newAdPlaybackState = adPlaybackState;
switch (event.getType()) {
case CUEPOINTS_CHANGED:
if (newAdPlaybackState.equals(AdPlaybackState.NONE)) {
newAdPlaybackState =
setVodAdGroupPlaceholders(
checkNotNull(streamManager).getCuePoints(), new AdPlaybackState(adsId));
}
break;View on GitHub (pinned to dd430f7053)
Solutions
- Ensure exactly one IMA SSAI MediaItem exists per Player: filter the playlist before submission and drop or replace duplicates.
- If multiple SSAI streams genuinely must play sequentially, create a new Player instance (release the old one) for each SSAI stream instead of putting both in one playlist.
- If the duplicate is unintentional, audit the code path that constructs MediaItems (queue/restore logic) and de-duplicate on the imasky scheme.
Example fix
// before player.setMediaItems(Arrays.asList(ssaiItem, ssaiItem)); // IllegalStateException // after List<MediaItem> items = new ArrayList<>(); items.add(ssaiItem); items.add(MediaItem.fromUri(plainVodUri)); // at most one SSAI item per player player.setMediaItems(items);
Defensive patterns
Strategy: validation
Validate before calling
static boolean hasMultipleSsaiItems(Player player) {
int count = 0;
for (int i = 0; i < player.getMediaItemCount(); i++) {
MediaItem mi = player.getMediaItemAt(i);
if (mi.localConfiguration != null
&& C.SSAI_SCHEME.equals(mi.localConfiguration.uri.getScheme())) {
if (++count > 1) return true;
}
}
return false;
} Prevention
- De-duplicate playlist entries on the imasky scheme before calling setMediaItems.
- Create a new Player per SSAI stream when sequences are required.
When it happens
Trigger: Adding two or more MediaItems built with ImaServerSideAdInsertionUriBuilder (scheme imasky, IMA authority) to the same Player playlist — either directly via player.addMediaItem/setMediaItems, or by rebuilding/concatenating playlists that each contain an SSAI item.
Common situations: Refactoring a single-item player into a playlist and blindly concatenating SSAI URIs; restoring a saved playlist that contains the SSAI item while also inserting a fresh one; a media queue feature that lets users add a live DAI stream twice.
Related errors
- Invalid URI scheme or authority.
- ${errorMessage} [errorCode: ${errorCode}]
- Unsupported stream format:${format}
- No unplayed ad group found before or at the start time us %d
- Unexpected color filter ${colorFilterSelection}
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/0443b9bf67e60d91.
Report an issue: GitHub.