{"record":{"id":"86c2fc6131ef7806","repo":"google/ExoPlayer","slug":"failed-to-initialize-decoder","errorCode":null,"errorMessage":"Failed to initialize decoder","messagePattern":"Failed to initialize decoder","errorType":"exception","errorClass":"FlacDecoderException","httpStatus":null,"severity":"critical","filePath":"extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java","lineNumber":68,"sourceCode":"    }\n  }\n\n  private static final int TEMP_BUFFER_SIZE = 8192; // The same buffer size as libflac.\n\n  private final long nativeDecoderContext;\n\n  @Nullable private ByteBuffer byteBufferData;\n  @Nullable private ExtractorInput extractorInput;\n  @Nullable private byte[] tempBuffer;\n  private boolean endOfExtractorInput;\n\n  public FlacDecoderJni() throws FlacDecoderException {\n    if (!FlacLibrary.isAvailable()) {\n      throw new FlacDecoderException(\"Failed to load decoder native libraries.\");\n    }\n    nativeDecoderContext = flacInit();\n    if (nativeDecoderContext == 0) {\n      throw new FlacDecoderException(\"Failed to initialize decoder\");\n    }\n  }\n\n  /**\n   * Sets the data to be parsed.\n   *\n   * @param byteBufferData Source {@link ByteBuffer}.\n   */\n  public void setData(ByteBuffer byteBufferData) {\n    this.byteBufferData = byteBufferData;\n    this.extractorInput = null;\n  }\n\n  /**\n   * Sets the data to be parsed.\n   *\n   * @param extractorInput Source {@link ExtractorInput}.\n   */","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoderJni.java#L50-L86","documentation":"Thrown by the FlacDecoderJni constructor when the native flacInit() call returns 0 (a NULL decoder context). Unlike the 'Failed to load decoder native libraries' error, the JNI library IS loaded, but the underlying native FLAC decoder object could not be created — almost always because the native code failed to allocate its decoder/stream-decoder state.","triggerScenarios":"Calling new FlacDecoderJni() (or playing a FLAC stream through the extension renderer) when FLAC__stream_decoder_new() inside flacInit() returns NULL, typically due to native memory exhaustion or a corrupted/incompatible native build.","commonSituations":"Running on a low-memory device or in a process that has already allocated many decoders (e.g. rapid codec reinstantiation during seek or playlist transitions); a mismatched or corrupted libflacJNI.so built against a different libflac version; rare native heap fragmentation on older 32-bit devices.","solutions":["Check for decoder/codec instance leaks: make sure the player and renderers are released before creating new ones, and avoid constructing FlacDecoderJni repeatedly in a loop.","Rebuild the FLAC extension ensuring the libflac version bundled matches the JNI wrapper (follow extensions/flac README exactly), then redeploy a clean build.","Reproduce with a trivial FLAC file to rule out file-specific corruption; if the error is sporadic, capture native memory usage (adb shell dumpsys meminfo) around the failure.","Migrate to androidx.media3, whose prebuilt FLAC support is continuously tested, if maintaining a custom NDK build is not required."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { new FlacDecoderJni(); } catch (FlacDecoderException e) { if (\"Failed to initialize decoder\".equals(e.getMessage())) { release other decoders, retry once, else surface error; } }","preventionTips":["Release player/decoder instances before creating new ones; avoid unbounded decoder churn during seeks.","Keep libflac and the JNI wrapper built from the same revision."],"tags":["flac","native","decoder","memory","initialization"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}