remotion-dev/remotion · error
Mvhd box is not found
Error message
Mvhd box is not found
What it means
Thrown by getTracksFromMoovBox while iterating each trak inside an MP4 moov box: it calls getMvhdBox(moovBox) and requires a non-null movie-header box. The mvhd (Movie Header Box) is mandatory in every conformant ISO-BMFF/MP4 file because it carries the movie timescale used to compute per-track start times. Its absence means the file is structurally invalid or truncated, so the parser refuses to fabricate track timing.
Source
Thrown at packages/media-parser/src/get-tracks.ts:214
const getCategorizedTracksFromMatroska = (
state: ParserState,
): MediaParserTrack[] => {
const {resolved} = getTracksFromMatroska({
structureState: state.structure,
webmState: state.webm,
});
return resolved;
};
export const getTracksFromMoovBox = (moovBox: MoovBox): MediaParserTrack[] => {
const mediaParserTracks: MediaParserTrack[] = [];
const tracks = getTraks(moovBox);
for (const trakBox of tracks) {
const mvhdBox = getMvhdBox(moovBox);
if (!mvhdBox) {
throw new Error('Mvhd box is not found');
}
const startTime = findTrackStartTimeInSeconds({
movieTimeScale: mvhdBox.timeScale,
trakBox,
});
const track = makeBaseMediaTrack(trakBox, startTime);
if (!track) {
continue;
}
mediaParserTracks.push(track);
}
return mediaParserTracks;
};
export const getTracksFromIsoBaseMedia = ({View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-mux or re-encode the source with a conformant tool (FFmpeg: `ffmpeg -i input -c copy -movflags +faststart out.mp4`) to guarantee a valid moov/mvhd.
- Verify the file is not truncated: check its size against the original and that the moov atom is fully downloaded (use `ffprobe` or a box dumper).
- If the input is untrusted, wrap parseMedia in try/catch and skip/reject files that fail structure validation.
- Report the file at https://remotion.dev/report if it plays in other players but fails here, so the parser can be made more tolerant.
Example fix
// before
await parseMedia({src: 'corrupt.mp4', fields: {}});
// after: validate with ffprobe first, then guard
import {execFileSync} from 'node:child_process';
const ok = execFileSync('ffprobe', ['-v','error',src]).toString() === '';
if (!ok) throw new Error('File rejected by ffprobe');
try {
await parseMedia({src, fields: {}});
} catch (e) {
if (String(e.message).includes('Mvhd box is not found')) {/* reject corrupt asset */}
else throw e;
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the asset has a valid moov/mvhd before parsing
import {execFileSync} from 'node:child_process';
function isStructurallyValidMp4(path: string): boolean {
try {
execFileSync('ffprobe', ['-v', 'error', '-show_entries', 'format=format_name', '-of', 'default=nw=1:nk=1', path], {stdio: 'pipe'});
return true;
} catch { return false; }
} Type guard
import type {MoovBox} from '@remotion/media-parser/boxes';
// Conceptual: validate moov has mvhd before calling getTracksFromMoovBox
const hasMvhd = (moov: MoovBox): boolean =>
moov.children.some(b => b.type === 'regular-box' && b.boxType === 'mvhd'); Try / catch
try {
await parseMedia({src, fields: {tracks: true}});
} catch (e) {
if (e instanceof Error && e.message === 'Mvhd box is not found') {
// reject corrupt asset, do not retry
throw new Error(`Rejected corrupt MP4 (missing mvhd): ${src}`);
}
throw e;
} Prevention
- Run ffprobe on ingested uploads and reject any file that fails before parsing.
- Re-mux untrusted assets with FFmpeg (-c copy) to normalize box structure.
- Validate file size / completeness (no truncated downloads) before parsing.
- For user-supplied media, wrap parseMedia in try/catch and isolate structurally-invalid files.
When it happens
Trigger: Parsing an MP4/MOV/fragmented-MP4 whose moov box is present but missing its mvhd child (corrupt header, truncated download, or a non-standard muxer). Reached via parseMedia / getTracksFromIsoBaseMedia when the container is detected as ISO-BMFF and a moov box is found but getMvhdBox returns null.
Common situations: A media file that was cut off mid-write, an MP4 produced by a buggy/proprietary muxer, a remuxed file whose moov was reconstructed incorrectly, or test fixtures hand-crafted without an mvhd. Also seen when a byte-range download only partially captured the moov atom.
Related errors
- No tkhd box found
- Expected stsz box in trak box
- Expected stco box in trak box
- Expected stsc box in trak box
- Expected stts box in trak box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/119bce6d43680fb8.
Report an issue: GitHub.