remotion-dev/remotion · error · Error
expected 0 bytes ${bytesRemaining}
Error message
expected 0 bytes ${bytesRemaining} What it means
Thrown at the end of parseMvhd() (movie header box). After reading every defined mvhd field for its version, leftover bytes remain: size - (bytesConsumed) !== 0. The declared mvhd size does not match the spec-mandated field layout, so the parser treats the box as malformed and aborts.
Source
Thrown at packages/media-parser/src/containers/iso-base-media/moov/mvhd.ts:108
iterator.getFixedPointSigned1616Number(),
iterator.getFixedPointSigned1616Number(),
iterator.getFixedPointSigned230Number(),
iterator.getFixedPointSigned1616Number(),
iterator.getFixedPointSigned1616Number(),
iterator.getFixedPointSigned230Number(),
];
// pre-defined
iterator.discard(4 * 6);
// next track id
const nextTrackId = iterator.getUint32();
volumeView.destroy();
const bytesRemaining = size - (iterator.counter.getOffset() - offset);
if (bytesRemaining !== 0) {
throw new Error('expected 0 bytes ' + bytesRemaining);
}
return {
creationTime: toUnixTimestamp(Number(creationTime)),
modificationTime: toUnixTimestamp(Number(modificationTime)),
timeScale,
durationInUnits: Number(durationInUnits),
durationInSeconds,
rate,
volume,
matrix: matrix as ThreeDMatrix,
nextTrackId,
type: 'mvhd-box',
boxSize: size,
offset,
};
};
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-mux with a compliant tool: ffmpeg -i in.mp4 -c copy out.mp4 (rebuilds mvhd with correct size).
- Validate with MP4Box -info in.mp4 or ffprobe; both flag box-size inconsistencies.
- Re-fetch the source if you suspect transfer corruption.
- Migrate to @remotion/mediabunny (parseMedia is deprecated).
Example fix
// before
const {durationInSeconds} = await parseMedia({src, reader: nodeReader});
// after
try {
const r = await parseMedia({src, reader: nodeReader});
} catch (err) {
if (err instanceof Error && /expected 0 bytes/.test(err.message)) {
// mvhd size mismatch — re-mux to rebuild the box
} else throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate box integrity before parsing:
// MP4Box -info in.mp4 (flags box-size mismatches)
// ffprobe -v warning in.mp4
import {execFileSync} from 'node:child_process';
function fileLooksIntact(file: string): boolean {
try {
execFileSync('ffprobe', ['-v','warning','-hide_banner', file], {encoding:'utf8', stdio:'pipe'});
return true;
} catch { return false; }
} Type guard
// mvhd size correctness is a deep binary property; not caller-type-guardable. // => typeGuard: null
Try / catch
try {
const {durationInSeconds} = await parseMedia({src, reader: nodeReader});
} catch (err) {
if (err instanceof Error && /expected 0 bytes/.test(err.message)) {
// mvhd size mismatch — re-mux to rebuild the box
} else {
throw err;
}
} Prevention
- Re-mux suspect files with ffmpeg to rebuild correctly-sized mvhd boxes.
- Validate with MP4Box -info / ffprobe before parsing.
- Re-fetch sources suspected of corruption.
- Migrate to @remotion/mediabunny (parseMedia is deprecated).
When it happens
Trigger: parseMedia({src}) on an MP4/MOV whose mvhd box size is inconsistent with its version-0 or version-1 layout — e.g. trailing padding bytes, a wrong size field, or a version the parser did not fully account for. Since mvhd carries the movie timescale, this also blocks all track registration.
Common situations: Files produced by non-compliant muxers that pad boxes incorrectly; hand-edited or patched MP4s; corrupted downloads where the mvhd size field is wrong.
Related errors
- Expected remaining bytes to be 0, got ${remaining}
- Movie timescale is not set
- read too many bytes - size: ${size}, read: ${iterator.counte
- Could not find number of channels
- Could not find sample rate
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/af3f08bcbb0139ed.
Report an issue: GitHub.