remotion-dev/remotion · error · Error
xing header was parsed wrong: read beyond available data
Error message
xing header was parsed wrong: read beyond available data
What it means
Thrown by parseXing() after consuming the flag-driven fields (numberOfFrames, fileSize, 100-byte TOC, vbrScale) when the running offset has moved past data.length. The comment above the check says extra trailing data is allowed, so the throw fires only when the standard fields themselves overran the buffer — i.e. the flags word claimed fields the buffer could not satisfy.
Source
Thrown at packages/media-parser/src/containers/mp3/parse-xing.ts:93
if (flags & BYTES_FLAG) {
fileSize = extractI4(data, offset);
offset += 4;
}
if (flags & TOC_FLAG) {
tableOfContents = data.slice(offset, offset + 100);
offset += 100;
}
if (flags & VBR_SCALE_FLAG) {
vbrScale = extractI4(data, offset);
offset += 4;
}
// Allow extra data after the standard Xing fields, as some encoders add additional information
if (offset > data.length) {
throw new Error('xing header was parsed wrong: read beyond available data');
}
return {
sampleRate,
numberOfFrames: numberOfFrames ?? null,
fileSize: fileSize ?? null,
tableOfContents: tableOfContents
? Array.from(tableOfContents.slice(0, 100))
: null,
vbrScale: vbrScale ?? null,
};
};
export const getSeekPointInBytes = ({
fileSize,
percentBetween0And100,
tableOfContents,
}: {View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure the full first MP3 frame (typically ~417+ bytes for MPEG1) is buffered before calling parseXing() — fetch a larger byte range or read the whole frame.
- Re-encode the file so a clean Xing tag is written: ffmpeg -i in.mp3 -c:a libmp3lame -q:a 2 out.mp3
- Wrap parseXing() in try/catch and fall back to CBR seek when it fails.
Example fix
// before const xing = parseXing(partialBuffer); // after: pass a buffer large enough for the whole first frame const FRAME_SIZE = mpegVersion === 1 ? 417 : 209; const xing = parseXing(firstFrame.subarray(0, FRAME_SIZE));
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the first frame buffer is large enough to hold all Xing fields (worst case ~417 bytes for MPEG-1).
const MIN_XING_BUF = 417;
if (firstFrame.length < MIN_XING_BUF) {
// fetch more bytes / wait for the full frame before calling parseXing
} Type guard
null
Try / catch
try {
const xing = parseXing(firstFrame);
} catch (err) {
if (err instanceof Error && err.message.startsWith('xing header was parsed wrong')) {
// buffer truncated: re-fetch full first frame and retry, or fall back to CBR
} else throw err;
} Prevention
- Buffer the entire first MP3 frame before parsing the Xing header.
- For network sources, request a byte range large enough to cover the first frame plus side info.
- Re-encode suspect files to regenerate a clean Xing tag.
When it happens
Trigger: A Xing header whose flags word is corrupt or whose TOC/fields are truncated (e.g. flags say TOC_FLAG is set but the buffer has fewer than 100 bytes remaining after numberOfFrames/fileSize). Also possible if a wrong xingOffset caused the flags to be read from the wrong position, yielding bogus large flags.
Common situations: Truncated first MP3 frame (e.g. only partial bytes fetched from a network range request); a malformed Xing tag from a buggy encoder; bit-flips in the flags word.
Related errors
- Invalid Xing header
- No MP3 info
- Cannot get duration of VBR MP3 file - no frames
- Cannot get duration of VBR MP3 file - no sample rate
- MP3 files with VBRI are currently unsupported because we hav
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/296a47f48dd9e3cf.
Report an issue: GitHub.