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

  1. 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.
  2. 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).
  3. If the input is untrusted, wrap parseMedia in try/catch and skip/reject files that fail structure validation.
  4. 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

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


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/119bce6d43680fb8. Report an issue: GitHub.