remotion-dev/remotion · error · Error
No moov box found in header segment
Error message
No moov box found in header segment
What it means
Thrown by getMoovAtom when the parser is handling an HLS/m3u8 stream that supplies an mp4HeaderSegment (a pre-fetched ISO structure used as the moov source for fMP4 segments), but getMoovFromFromIsoStructure returns null because no top-level moov-box exists in that header segment. The header segment is expected to bootstrap track metadata; if it lacks moov, the parser cannot proceed with fragmented segments.
Source
Thrown at packages/media-parser/src/containers/iso-base-media/get-moov-atom.ts:29
MediaParserOnVideoTrack,
} from '../../webcodec-sample-types';
import type {IsoBaseMediaBox} from './base-media-box';
import type {MoovBox} from './moov/moov';
import {processBox} from './process-box';
import {getMoovFromFromIsoStructure} from './traversal';
export const getMoovAtom = async ({
endOfMdat,
state,
}: {
state: ParserState;
endOfMdat: number;
}): Promise<MoovBox> => {
const headerSegment = state.m3uPlaylistContext?.mp4HeaderSegment;
if (headerSegment) {
const segment = getMoovFromFromIsoStructure(headerSegment);
if (!segment) {
throw new Error('No moov box found in header segment');
}
return segment;
}
const start = Date.now();
Log.verbose(state.logLevel, 'Starting second fetch to get moov atom');
const {reader} = await state.readerInterface.read({
src: state.src,
range: endOfMdat,
controller: state.controller,
logLevel: state.logLevel,
prefetchCache: state.prefetchCache,
});
const onAudioTrack: MediaParserOnAudioTrack | null = state.onAudioTrack
? async ({track, container}) => {
await registerAudioTrack({View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Verify the HLS playlist has a valid #EXT-X-MAP pointing to a real fMP4 initialization segment containing moov.
- Fetch the init segment URL directly and inspect it with `ffprobe` to confirm it contains moov.
- Regenerate the HLS playlist with a conformant packager (Bento4, ffmpeg HLS muxer, Shaka).
- If the init segment is dynamic, ensure your CDN does not cache a media segment in its place.
Example fix
// before
await parseMedia({ src: 'https://example.com/stream.m3u8' });
// after
// Pre-validate the playlist's init segment referenced by #EXT-X-MAP
const initRes = await fetch(initSegmentUrl);
const initBuf = new Uint8Array(await initRes.arrayBuffer());
const hasMoov = String.fromCharCode(...initBuf.subarray(4, 8)) === 'moov'
|| initBuf.some((_, i) => String.fromCharCode(...initBuf.subarray(i + 4, i + 8)) === 'moov');
if (!hasMoov) throw new Error('HLS init segment is missing moov; check #EXT-X-MAP');
await parseMedia({ src: 'https://example.com/stream.m3u8' }); Defensive patterns
Strategy: validation
Validate before calling
// Validate the HLS init segment contains moov before handing the playlist to media-parser
async function initSegmentHasMoov(initUrl: string): Promise<boolean> {
const res = await fetch(initUrl);
const buf = new Uint8Array(await res.arrayBuffer());
for (let i = 4; i + 4 <= buf.length; i++) {
if (buf[i] === 0x6d && buf[i + 1] === 0x6f && buf[i + 2] === 0x6f && buf[i + 3] === 0x76) return true;
}
return false;
} Type guard
import type {IsoBaseMediaStructure} from '../../parse-result';
function structureHasMoov(s: IsoBaseMediaStructure | null): boolean {
return !!s && s.boxes.some((b) => b.type === 'moov-box');
} Try / catch
try {
await parseMedia({ src: playlistUrl });
} catch (err) {
if (/No moov box found in header segment/i.test(String(err?.message))) {
throw new Error('HLS init segment (#EXT-X-MAP) is missing moov. Fix the playlist or re-package the stream.');
}
throw err;
} Prevention
- Always include a valid #EXT-X-MAP init segment that contains moov in HLS playlists you produce.
- Fetch the init segment URL yourself and verify it contains a moov box before parsing.
- Use a conformant HLS packager (Bento4 mp4dash, ffmpeg HLS, Shaka packager).
- Make sure your CDN caches the init segment correctly and never substitutes a media segment.
When it happens
Trigger: An HLS playlist whose #EXT-X-MAP or fMP4 initialization segment does not contain a moov atom (e.g. it is actually a raw fMP4 segment without the init, the wrong segment was referenced, or the segment was truncated). Reachable when state.m3uPlaylistContext.mp4HeaderSegment is populated but its boxes array has no 'moov-box' entry.
Common situations: Misconfigured HLS origin that points #EXT-X-MAP at a media segment instead of the init segment. CDN caching the wrong segment under the init URL. Partial download of the init segment. Playlist generator bug that omits the init segment.
Related errors
- No moov box found
- no video and no audio tracks
- No moov atom found
- No trak box found
- Expected tkhd box in trak box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/1b36ab6719b294f0.
Report an issue: GitHub.