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

  1. Ensure exactly one IMA SSAI MediaItem exists per Player: filter the playlist before submission and drop or replace duplicates.
  2. 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.
  3. 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

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


AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14). Data as JSON: /api/errors/0443b9bf67e60d91. Report an issue: GitHub.