{"record":{"id":"e5a31a246079c24f","repo":"google/ExoPlayer","slug":"initialization-data-must-be-of-length-1","errorCode":null,"errorMessage":"Initialization data must be of length 1","messagePattern":"Initialization data must be of length 1","errorType":"exception","errorClass":"FlacDecoderException","httpStatus":null,"severity":"error","filePath":"extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java","lineNumber":68,"sourceCode":"   * Creates a Flac decoder.\n   *\n   * @param numInputBuffers The number of input buffers.\n   * @param numOutputBuffers The number of output buffers.\n   * @param maxInputBufferSize The maximum required input buffer size if known, or {@link\n   *     Format#NO_VALUE} otherwise.\n   * @param initializationData Codec-specific initialization data. It should contain only one entry\n   *     which is the flac file header.\n   * @throws FlacDecoderException Thrown if an exception occurs when initializing the decoder.\n   */\n  public FlacDecoder(\n      int numInputBuffers,\n      int numOutputBuffers,\n      int maxInputBufferSize,\n      List<byte[]> initializationData)\n      throws FlacDecoderException {\n    super(new DecoderInputBuffer[numInputBuffers], new SimpleDecoderOutputBuffer[numOutputBuffers]);\n    if (initializationData.size() != 1) {\n      throw new FlacDecoderException(\"Initialization data must be of length 1\");\n    }\n    decoderJni = new FlacDecoderJni();\n    decoderJni.setData(ByteBuffer.wrap(initializationData.get(0)));\n    try {\n      streamMetadata = decoderJni.decodeStreamMetadata();\n    } catch (ParserException e) {\n      throw new FlacDecoderException(\"Failed to decode StreamInfo\", e);\n    } catch (IOException e) {\n      // Never happens.\n      throw new IllegalStateException(e);\n    }\n\n    int initialInputBufferSize =\n        maxInputBufferSize != Format.NO_VALUE ? maxInputBufferSize : streamMetadata.maxFrameSize;\n    setInitialInputBufferSize(initialInputBufferSize);\n  }\n\n  @Override","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/FlacDecoder.java#L50-L86","documentation":"FlacDecoderException thrown by the FlacDecoder constructor when the initializationData list does not contain exactly one entry. The FLAC extractor puts the raw STREAMINFO metadata block (the first metadata block of the file) into initializationData as its single element; any other size means the stream was not properly parsed as FLAC or the format was misdetected.","triggerScenarios":"Constructing FlacDecoder from a Format whose initializationData was produced by the wrong extractor (e.g. an ID3/other parser), was truncated, or was constructed manually with zero or multiple entries; feeding FLAC data through a generic pipeline that split or dropped the header block.","commonSituations":"Wrong extractor selected by DefaultExtractorsFactory for a file with a non-standard start; hand-built Format objects in tests or custom extractors; .flac files with junk prepended so sniffing picks another extractor.","solutions":["Ensure playback goes through the FlacExtractor (enable it via DefaultExtractorsFactory.setFlacExtractorArguments or the extension's extractor) so initializationData carries exactly the STREAMINFO block","If you build the Format yourself, pass Collections.singletonList(streamInfoBytes) where the bytes are the 34-byte STREAMINFO block from the file header","Verify the input actually is FLAC (check the 'fLaC' magic) before selecting the FLAC pipeline","Catch FlacDecoderException during renderer init to fall back to platform FLAC decoding (API 27+) when available"],"exampleFix":"// before: hand-built Format with wrong init data shape\nFormat format = new Format.Builder()\n    .setSampleMimeType(MimeTypes.AUDIO_FLAC)\n    .setInitializationData(Collections.emptyList()) // size 0 -> throws\n    .build();\n\n// after: single STREAMINFO entry from the file header\nFormat format = new Format.Builder()\n    .setSampleMimeType(MimeTypes.AUDIO_FLAC)\n    .setInitializationData(Collections.singletonList(streamInfoBlockBytes))\n    .build();","handlingStrategy":"validation","validationCode":"boolean isFlacInitializationData(List<byte[]> init) {\n  if (init.size() != 1) return false;\n  byte[] block = init.get(0);\n  return block.length == 34; // FLAC STREAMINFO block payload size\n}\n\nif (!isFlacInitializationData(format.initializationData)) {\n  // refuse to construct FlacDecoder; select another FLAC pipeline or fail clearly\n}","typeGuard":null,"tryCatchPattern":"try {\n  decoder = new FlacDecoder(numIn, numOut, maxIn, format.initializationData);\n} catch (FlacDecoderException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"length 1\")) {\n    // extractor produced wrong init data: re-extract with FlacExtractor and retry\n    format = reExtractWithFlacExtractor(inputUri);\n    decoder = new FlacDecoder(numIn, numOut, maxIn, format.initializationData);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Let the FLAC extension's own extractor produce the Format so initializationData always holds exactly the STREAMINFO block","When constructing Format manually, always pass a single 34-byte stream-info entry","Sniff for the 'fLaC' magic before routing files into the FLAC pipeline"],"tags":["android","flac","decoder-initialization","metadata"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}