google/ExoPlayer · error · IllegalStateException

Failed to find cue point

Error message

Failed to find cue point

What it means

Thrown by AdTagLoader when an IMA SDK cue point (an ad break time reported by the ads SDK) cannot be matched to any ad group in the current AdPlaybackState. The code converts the cue point to microseconds and searches for an ad group within THRESHOLD_AD_MATCH_US; if none matches, the mapping between what IMA reports and what ExoPlayer scheduled is broken, so it fails fast rather than misattributing ads.

Source

Thrown at extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/AdTagLoader.java:1281

              playerPositionUs, msToUs(contentDurationMs));
    }
    return adGroupIndex;
  }

  private int getAdGroupIndexForCuePointTimeSeconds(double cuePointTimeSeconds) {
    // We receive initial cue points from IMA SDK as floats. This code replicates the same
    // calculation used to populate adGroupTimesUs (having truncated input back to float, to avoid
    // failures if the behavior of the IMA SDK changes to provide greater precision).
    float cuePointTimeSecondsFloat = (float) cuePointTimeSeconds;
    long adPodTimeUs = Math.round((double) cuePointTimeSecondsFloat * C.MICROS_PER_SECOND);
    for (int adGroupIndex = 0; adGroupIndex < adPlaybackState.adGroupCount; adGroupIndex++) {
      long adGroupTimeUs = adPlaybackState.getAdGroup(adGroupIndex).timeUs;
      if (adGroupTimeUs != C.TIME_END_OF_SOURCE
          && Math.abs(adGroupTimeUs - adPodTimeUs) < THRESHOLD_AD_MATCH_US) {
        return adGroupIndex;
      }
    }
    throw new IllegalStateException("Failed to find cue point");
  }

  private String getAdMediaInfoString(@Nullable AdMediaInfo adMediaInfo) {
    @Nullable AdInfo adInfo = adInfoByAdMediaInfo.get(adMediaInfo);
    return "AdMediaInfo["
        + (adMediaInfo == null ? "null" : adMediaInfo.getUrl())
        + ", "
        + adInfo
        + "]";
  }

  private static long getContentPeriodPositionMs(
      Player player, Timeline timeline, Timeline.Period period) {
    long contentWindowPositionMs = player.getContentPosition();
    if (timeline.isEmpty()) {
      return contentWindowPositionMs;
    } else {
      return contentWindowPositionMs

View on GitHub (pinned to dd430f7053)

Solutions

  1. Verify the ad tag (VMAP break times) is self-consistent and does not declare near-duplicate breaks closer together than THRESHOLD_AD_MATCH_US.
  2. Update the IMA SDK and ExoPlayer IMA extension to matching, current versions — precision and rounding behavior of cue points has changed across IMA releases.
  3. Do not share one AdTagLoader/AdsLoader instance across media items with different ad configurations; release and recreate per stream.
  4. If you construct AdPlaybackState yourself, ensure adGroupTimesUs are derived with the same float-truncation + Math.round(µs) math shown in the source, so IMA-reported cue points land within the threshold.
Defensive patterns

Strategy: validation

Validate before calling

// Before resolving cue points, confirm a matching ad group exists:
float cueFloat = (float) cuePointTimeSeconds;
long podUs = Math.round((double) cueFloat * C.MICROS_PER_SECOND);
boolean matches = false;
for (int i = 0; i < adPlaybackState.adGroupCount; i++) {
  long t = adPlaybackState.getAdGroup(i).timeUs;
  if (t != C.TIME_END_OF_SOURCE && Math.abs(t - podUs) < 10_000L) matches = true;
}
if (!matches) Log.w(TAG, "Cue point " + podUs + "us has no ad group; check ad tag");

Try / catch

try { int idx = resolveAdGroupIndexForCuePoint(cuePointTimeSeconds); } catch (IllegalStateException e) { Log.w(TAG, "Cue point mismatch — verify ad tag consistency", e); skipCuePoint(); }

Prevention

When it happens

Trigger: Calling the cue-point resolution path after IMA fires ADS_LOADER / content resume with cue points whose times differ from the adGroupTimesUs ExoPlayer derived at preparation time — e.g. the ad tag declares breaks at 15s but the IMA SDK later reports 15.05s beyond the match threshold, or ad groups were removed/modified concurrently.

Common situations: A mis-authored VAST/VMAP ad tag whose cue points drift from the declared break times; an IMA SDK version change that alters cue-point precision or timing; concurrent modification of AdPlaybackState (e.g. server-side ad insertion data merged while client-side cue points arrive); playlists where the same AdsLoader is reused across items with different ad break layouts.

Related errors


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