google/ExoPlayer · error · AudioSink.InitializationException

audioTrackState != AudioTrack.STATE_INITIALIZED

audioTrackState != AudioTrack.STATE_INITIALIZED

Error message

AudioTrack init failed {audioTrackState} Config({sampleRate}, {channelConfig}, {bufferSize}) {format}{isRecoverable? \ (recoverable\)}

What it means

After AudioTrack construction succeeds, DefaultAudioSink checks audioTrack.getState(); if it is not AudioTrack.STATE_INITIALIZED (commonly STATE_UNINITIALIZED or STATE_NO_STATIC_DATA after a native init failure), it releases the track and throws AudioSink.InitializationException carrying the actual state, sample rate, channel config, buffer size, and the input format. isRecoverable is true only in offload mode, signaling the player may retry without offload; otherwise the audio renderer is treated as failed for this sink configuration.

Source

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

        throw new InitializationException(
            AudioTrack.STATE_UNINITIALIZED,
            outputSampleRate,
            outputChannelConfig,
            bufferSize,
            inputFormat,
            /* isRecoverable= */ outputModeIsOffload(),
            e);
      }

      int state = audioTrack.getState();
      if (state != AudioTrack.STATE_INITIALIZED) {
        try {
          audioTrack.release();
        } catch (Exception e) {
          // The track has already failed to initialize, so it wouldn't be that surprising if
          // release were to fail too. Swallow the exception.
        }
        throw new InitializationException(
            state,
            outputSampleRate,
            outputChannelConfig,
            bufferSize,
            inputFormat,
            /* isRecoverable= */ outputModeIsOffload(),
            /* audioTrackException= */ null);
      }
      return audioTrack;
    }

    private AudioTrack createAudioTrack(
        boolean tunneling, AudioAttributes audioAttributes, int audioSessionId) {
      if (Util.SDK_INT >= 29) {
        return createAudioTrackV29(tunneling, audioAttributes, audioSessionId);
      } else if (Util.SDK_INT >= 21) {
        return createAudioTrackV21(tunneling, audioAttributes, audioSessionId);
      } else {

View on GitHub (pinned to dd430f7053)

Solutions

  1. Handle PlaybackException with ERROR_CODE_AUDIO_TRACK_INIT_FAILED: if the underlying InitializationException.isRecoverable(), retry playback with offload disabled.
  2. Release and rebuild the player when this fires repeatedly (HAL resource leaks usually clear after releasing the AudioTrack).
  3. Reduce simultaneous player/AudioTrack instances (e.g. preloading pools) to avoid native track exhaustion.
  4. Capture audioTrackState and format from the exception for the bug report; test the same media on other devices to isolate HAL issues.

Example fix

// before
player.addListener(new Player.Listener() {}); // no error handling

// after
player.addListener(new Player.Listener() {
  @Override public void onPlayerError(PlaybackException error) {
    if (error.getErrorCode()
        == PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED) {
      // rebuild player without offload and retry current item
      restartWithoutOffload(player.getCurrentMediaItem());
    }
  }
});
Defensive patterns

Strategy: fallback

Validate before calling

AudioTrack probe = buildProbeTrack(encoding, sampleRate, channelConfig, bufferBytes);
int state = probe.getState();
probe.release();
if (state != AudioTrack.STATE_INITIALIZED) {
  // plan PCM fallback now, before attaching the item to the player
}

Try / catch

player.addListener(new Player.Listener() {
  @Override public void onPlayerError(PlaybackException e) {
    if (e.getErrorCode()
        == PlaybackException.ERROR_CODE_AUDIO_TRACK_INIT_FAILED) {
      releaseAndRebuildPlayer(currentMediaItem); // clears native track leak
    }
  }
});

Prevention

When it happens

Trigger: The framework AudioTrack constructor returns an uninitialized track — native allocation failure, unsupported offload/passthrough configuration accepted by the constructor but rejected during init, or resource exhaustion (too many tracks open).

Common situations: Low-memory conditions exhausting AudioTrack/AF Track objects; OEM audio HAL limits on concurrent compressed outputs; switching quickly between offload and normal items in a playlist; devices with buggy audio HALs reporting STATE_UNINITIALIZED for valid configs.

Related errors


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