{"record":{"id":"5e25b18c75eb2639","repo":"remotion-dev/remotion","slug":"expected-layer-i-ii-or-iii","errorCode":null,"errorMessage":"Expected Layer I, II or III","messagePattern":"Expected Layer I, II or III","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/mp3/parse-packet-header.ts","lineNumber":206,"sourceCode":"\tif (\n\t\taudioVersionId !== 0b11 &&\n\t\taudioVersionId !== 0b10 &&\n\t\taudioVersionId !== 0b00\n\t) {\n\t\tthrow new Error('Expected MPEG Version 1 or 2');\n\t}\n\n\tconst mpegVersion = audioVersionId === 0b11 ? 1 : (2 as MpegVersion);\n\n\tconst layerBits = iterator.getBits(2);\n\t/**\n   * 00 - reserved\n     01 - Layer III\n     10 - Layer II\n     11 - Layer I\n   */\n\tif (layerBits === 0b00) {\n\t\tthrow new Error('Expected Layer I, II or III');\n\t}\n\n\tconst layer = layerBits === 0b11 ? 1 : layerBits === 0b10 ? 2 : 3;\n\n\titerator.getBits(1); // 0b1 means that there is no CRC, 0b0 means there is. Not validating checksum though\n\n\tconst bitrateIndex = iterator.getBits(4);\n\tconst bitrateInKbit = getBitrateKB({\n\t\tbits: bitrateIndex,\n\t\tmpegVersion,\n\t\tlevel: layer as Level,\n\t});\n\tif (bitrateInKbit === 'bad') {\n\t\tthrow new Error('Invalid bitrate');\n\t}\n\n\tif (bitrateInKbit === 'free') {\n\t\tthrow new Error('Free bitrate not supported');","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/mp3/parse-packet-header.ts#L188-L224","documentation":"Thrown by `innerParseMp3PacketHeader` when the 2-bit layer field equals `0b00`, which is marked 'reserved' in the MPEG specification. Valid layer values are `0b01` (Layer III), `0b10` (Layer II), and `0b11` (Layer I); `0b00` is forbidden.","triggerScenarios":"During frame header parsing (`parse-packet-header.ts:205-207`), the `layerBits` field (read after the audio version ID) is `0b00`. No MPEG layer maps to this value.","commonSituations":"Corrupt or damaged frame headers. Non-MPEG data being interpreted as an audio frame. Files with bit-level corruption. Random byte sequences encountered during parsing due to offset misalignment.","solutions":["Validate the file with `ffprobe -i file.mp3` to confirm it's genuine MPEG audio.","Re-encode the file from a source that produces valid MPEG Layer II or III audio.","Check for partial downloads, disk corruption, or transfer errors.","Report the file at remotion.dev/report if it triggers this on a seemingly valid MP3."],"exampleFix":"# verify and re-encode\nffprobe -v error -i input.mp3\nffmpeg -i input.mp3 -codec:a libmp3lame output.mp3","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await parseMedia({src, fields: {durationInSeconds: true}});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Expected Layer I, II or III') {\n    console.error('The MP3 frame header contains a reserved MPEG layer value.');\n  }\n  throw e;\n}","preventionTips":["Validate MP3 files with ffprobe to confirm valid MPEG layer bits.","Re-encode files from a known-good source if frame headers are corrupt.","Check for data corruption from incomplete downloads.","Use try-catch around parseMedia for untrusted files."],"tags":["mp3","corrupt-file","invalid-header","mpeg-layer","mpeg-spec"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}