remotion-dev/remotion · error
Only supporting layer 0 for .aac
Error message
Only supporting layer 0 for .aac
What it means
Thrown by parseAac when the 2-bit 'layer' field in an ADTS header is non-zero. Per the ADTS specification, valid AAC streams must have layer=0 (indicating MPEG-4 Audio). A non-zero layer means the bitstream is either not AAC or the header is corrupted, so the parser refuses to continue.
Source
Thrown at packages/media-parser/src/containers/aac/parse-aac.ts:29
export const parseAac = async (state: ParserState): Promise<ParseResult> => {
const {iterator} = state;
const startOffset = iterator.counter.getOffset();
iterator.startReadingBits();
const syncWord = iterator.getBits(12);
if (syncWord !== 0xfff) {
throw new Error('Invalid syncword: ' + syncWord);
}
const id = iterator.getBits(1);
if (id !== 0) {
throw new Error('Only supporting MPEG-4 for .aac');
}
const layer = iterator.getBits(2);
if (layer !== 0) {
throw new Error('Only supporting layer 0 for .aac');
}
const protectionAbsent = iterator.getBits(1); // protection absent
const audioObjectType = iterator.getBits(2); // 1 = 'AAC-LC'
const samplingFrequencyIndex = iterator.getBits(4);
const sampleRate = getSampleRateFromSampleFrequencyIndex(
samplingFrequencyIndex,
);
iterator.getBits(1); // private bit
const channelConfiguration = iterator.getBits(3);
const codecPrivate = createAacCodecPrivate({
audioObjectType,
sampleRate,
channelConfiguration,
codecPrivate: null,
});
iterator.getBits(1); // originalityView on GitHub (pinned to 78fe4bb3fd)
Solutions
- Check the actual format with `ffprobe input.aac` — if it reports MP3 or another codec, rename/re-handle accordingly.
- If ID3 tags are prepended, strip them: `ffmpeg -i input.aac -c:a copy -map_metadata -1 output.aac`.
- Re-encode from a known-good source to produce valid ADTS: `ffmpeg -i input.wav -c:a aac -f adts output.aac`.
- Switch to Mediabunny (https://www.remotion.dev/docs/mediabunny/metadata) for broader format handling.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: verify ADTS layer bits are 0 (bits 13-14 of ADTS header)
async function isAdtsLayerZero(filePath: string): Promise<boolean> {
const buf = await readFile(filePath);
if (buf.length < 2) return false;
// Byte 1, bits 1-2 = layer field; should be 00
return (buf[1] & 0x06) === 0x00;
} Try / catch
try {
const result = await parseMedia({src, fields: {/* ... */}});
} catch (e) {
if (e instanceof Error && e.message === 'Only supporting layer 0 for .aac') {
console.error('ADTS layer is non-zero. File may be corrupt or mislabeled. Run: ffprobe <file>');
} else {
throw e;
}
} Prevention
- Verify the actual audio format with ffprobe before parsing.
- Strip ID3 tags and other prepended metadata that could misalign the parser.
- Re-encode from a known-good source if the file is corrupt.
- Migrate to Mediabunny for more robust format handling.
When it happens
Trigger: Parsing a .aac file where the ADTS header's layer field (bits 13-14 after sync) is 1, 2, or 3 instead of 0. This can result from bit corruption, a file that is actually MP3 with an AAC extension, or a misaligned read position.
Common situations: Files mislabeled with a .aac extension that are actually MP3 or another MPEG audio layer. Corrupted downloads where header bits are flipped. Byte streams with a prepended ID3 tag or other metadata that offsets the read position.
Related errors
- Invalid syncword: ${syncWord}
- Unexpected sampling frequency index ${samplingFrequencyIndex
- Invalid channel configuration ${channelConfiguration}
- Only supporting MPEG-4 for .aac
- Invalid ADTS header
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/171af76424de1a1a.
Report an issue: GitHub.