google/ExoPlayer · warning · AudioSink.InvalidAudioTrackTimestampException

Spurious audio timestamp (system clock mismatch): {audioTime

Error message

Spurious audio timestamp (system clock mismatch): {audioTimestampPositionFrames}, {audioTimestampSystemTimeUs}, {systemTimeUs}, {playbackPositionUs}, {submittedFrames}, {writtenFrames}

What it means

DefaultAudioSink listens to AudioTimestamp (via AudioTrack.getTimestamp) to keep playback positions accurate. A timestamp frame position that is farther in the future than the frames actually submitted to the track indicates the device's timestamp clock disagrees with the system clock (a known firmware/driver bug). Depending on failOnSpuriousAudioTimestamp (DefaultAudioSink.Builder experimental flag, default false), the sink either logs a warning ('Spurious audio timestamp (system clock mismatch)...') or throws InvalidAudioTrackTimestampException with the same diagnostic tuple: position frames, timestamp system time, current system time, playback position, submitted and written frames.

Source

Thrown at library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java:1994

        long audioTimestampPositionFrames,
        long audioTimestampSystemTimeUs,
        long systemTimeUs,
        long playbackPositionUs) {
      String message =
          "Spurious audio timestamp (system clock mismatch): "
              + audioTimestampPositionFrames
              + ", "
              + audioTimestampSystemTimeUs
              + ", "
              + systemTimeUs
              + ", "
              + playbackPositionUs
              + ", "
              + getSubmittedFrames()
              + ", "
              + getWrittenFrames();
      if (failOnSpuriousAudioTimestamp) {
        throw new InvalidAudioTrackTimestampException(message);
      }
      Log.w(TAG, message);
    }

    @Override
    public void onInvalidLatency(long latencyUs) {
      Log.w(TAG, "Ignoring impossibly large audio latency: " + latencyUs);
    }

    @Override
    public void onPositionAdvancing(long playoutStartSystemTimeMs) {
      if (listener != null) {
        listener.onPositionAdvancing(playoutStartSystemTimeMs);
      }
    }

    @Override
    public void onUnderrun(int bufferSize, long bufferSizeMs) {

View on GitHub (pinned to dd430f7053)

Solutions

  1. Keep the default behavior (do not call setFailOnSpuriousAudioTimestamp(true)) so mismatches are only logged.
  2. If you need fail-fast in QA builds, wrap playback in a catch for InvalidAudioTrackTimestampException and recreate the player to resynchronize.
  3. Report the device model/Android version with the diagnostic tuple — this is a device firmware issue, not app logic.
  4. Periodically re-sync or restart playback on affected devices when warnings spam the log.

Example fix

// before
new DefaultAudioSink.Builder(ctx)
    .setFailOnSpuriousAudioTimestamp(true) // throws on flaky devices
    .build();

// after
new DefaultAudioSink.Builder(ctx)
    .setFailOnSpuriousAudioTimestamp(false) // default: log-only
    .build();
Defensive patterns

Strategy: try-catch

Validate before calling

// before enabling fail-fast behavior, screen known-affected devices
boolean riskyDevice = Build.MODEL in AFFECTED_MODELS;
sinkBuilder.setFailOnSpuriousAudioTimestamp(!riskyDevice);

Try / catch

try {
  player.play();
} catch (Exception e) {
  if (e instanceof AudioSink.InvalidAudioTrackTimestampException
      || e.getCause() instanceof AudioSink.InvalidAudioTrackTimestampException) {
    recreatePlayerAndSeekTo(player.getCurrentPosition()); // resync timestamps
  }
}

Prevention

When it happens

Trigger: A device AudioTrack reports a timestamp whose audioTimestampSystemTimeUs implies more audio played than has been written — clock skew or buggy timestamping on certain chipsets — and the app enabled setFailOnSpuriousAudioTimestamp(true) on the sink builder.

Common situations: Bespoke/older firmware or emulators with drifting CLOCK_MONOTONIC vs audio DSP clocks; long playback sessions on affected devices; users enabling the fail-fast experimental flag for test builds; usually benign if left at the default warning behavior.

Related errors


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