{"record":{"id":"119bce6d43680fb8","repo":"remotion-dev/remotion","slug":"mvhd-box-is-not-found","errorCode":null,"errorMessage":"Mvhd box is not found","messagePattern":"Mvhd box is not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/get-tracks.ts","lineNumber":214,"sourceCode":"const getCategorizedTracksFromMatroska = (\n\tstate: ParserState,\n): MediaParserTrack[] => {\n\tconst {resolved} = getTracksFromMatroska({\n\t\tstructureState: state.structure,\n\t\twebmState: state.webm,\n\t});\n\n\treturn resolved;\n};\n\nexport const getTracksFromMoovBox = (moovBox: MoovBox): MediaParserTrack[] => {\n\tconst mediaParserTracks: MediaParserTrack[] = [];\n\tconst tracks = getTraks(moovBox);\n\n\tfor (const trakBox of tracks) {\n\t\tconst mvhdBox = getMvhdBox(moovBox);\n\t\tif (!mvhdBox) {\n\t\t\tthrow new Error('Mvhd box is not found');\n\t\t}\n\n\t\tconst startTime = findTrackStartTimeInSeconds({\n\t\t\tmovieTimeScale: mvhdBox.timeScale,\n\t\t\ttrakBox,\n\t\t});\n\t\tconst track = makeBaseMediaTrack(trakBox, startTime);\n\t\tif (!track) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tmediaParserTracks.push(track);\n\t}\n\n\treturn mediaParserTracks;\n};\n\nexport const getTracksFromIsoBaseMedia = ({","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/get-tracks.ts#L196-L232","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait parseMedia({src: 'corrupt.mp4', fields: {}});\n\n// after: validate with ffprobe first, then guard\nimport {execFileSync} from 'node:child_process';\nconst ok = execFileSync('ffprobe', ['-v','error',src]).toString() === '';\nif (!ok) throw new Error('File rejected by ffprobe');\ntry {\n  await parseMedia({src, fields: {}});\n} catch (e) {\n  if (String(e.message).includes('Mvhd box is not found')) {/* reject corrupt asset */}\n  else throw e;\n}","handlingStrategy":"validation","validationCode":"// Validate the asset has a valid moov/mvhd before parsing\nimport {execFileSync} from 'node:child_process';\nfunction isStructurallyValidMp4(path: string): boolean {\n  try {\n    execFileSync('ffprobe', ['-v', 'error', '-show_entries', 'format=format_name', '-of', 'default=nw=1:nk=1', path], {stdio: 'pipe'});\n    return true;\n  } catch { return false; }\n}","typeGuard":"import type {MoovBox} from '@remotion/media-parser/boxes';\n// Conceptual: validate moov has mvhd before calling getTracksFromMoovBox\nconst hasMvhd = (moov: MoovBox): boolean =>\n  moov.children.some(b => b.type === 'regular-box' && b.boxType === 'mvhd');","tryCatchPattern":"try {\n  await parseMedia({src, fields: {tracks: true}});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Mvhd box is not found') {\n    // reject corrupt asset, do not retry\n    throw new Error(`Rejected corrupt MP4 (missing mvhd): ${src}`);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["mp4","iso-bmff","corrupt-file","media-parser"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}