remotion-dev/remotion · error · Error
Read past end of file
Error message
Read past end of file
What it means
Thrown during the second fetch performed by getMoovAtom (when moov sits at the end of the file and the parser must range-request the tail) if iterator.counter.getOffset() + endOfMdat exceeds state.contentLength. This means the parser consumed more bytes than the file is supposed to contain — typically because contentLength was misreported or the actual response body is larger/structured differently than declared.
Source
Thrown at packages/media-parser/src/containers/iso-base-media/get-moov-atom.ts:124
logLevel: state.logLevel,
onlyIfMoovAtomExpected: {
tracks: tracksState,
isoState: null,
movieTimeScaleState: state.iso.movieTimeScale,
onAudioTrack,
onVideoTrack,
registerVideoSampleCallback: () => Promise.resolve(),
registerAudioSampleCallback: () => Promise.resolve(),
},
onlyIfMdatAtomExpected: null,
contentLength: state.contentLength - endOfMdat,
});
if (box.type === 'box') {
boxes.push(box.box);
}
if (iterator.counter.getOffset() + endOfMdat > state.contentLength) {
throw new Error('Read past end of file');
}
if (iterator.counter.getOffset() + endOfMdat === state.contentLength) {
break;
}
}
const moov = boxes.find((b) => b.type === 'moov-box');
if (!moov) {
throw new Error('No moov box found');
}
Log.verbose(
state.logLevel,
`Finished fetching moov atom in ${Date.now() - start}ms`,
);
return moov;View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure the readerInterface honors the requested byte range and the source reports a stable Content-Length.
- Pre-fetch the file size with a HEAD request and pass an accurate contentLength to parseMedia.
- If the source is a growing file, snapshot it to a stable URL before parsing.
- Implement a readerInterface that clamps reads to contentLength to avoid overshoot.
Example fix
// before
await parseMedia({ src: growingUrl, readerInterface: customReader });
// after
// Snapshot the current size and use a byte-serving endpoint
const head = await fetch(growingUrl, { method: 'HEAD' });
const size = Number(head.headers.get('content-length'));
await parseMedia({
src: `${growingUrl}?snapshot=${size}`,
readerInterface: rangeServingReader,
}); Defensive patterns
Strategy: validation
Validate before calling
// Ensure contentLength is accurate and the reader honors ranges
async function verifyStableSize(url: string): Promise<number> {
const h1 = await fetch(url, { method: 'HEAD' });
const size1 = Number(h1.headers.get('content-length'));
const h2 = await fetch(url, { method: 'HEAD' });
const size2 = Number(h2.headers.get('content-length'));
if (!Number.isFinite(size1) || size1 !== size2) throw new Error('Source size is unstable; snapshot before parsing');
return size1;
} Try / catch
try {
await parseMedia({ src, fields: { duration: true } });
} catch (err) {
if (/Read past end of file/i.test(String(err?.message))) {
throw new Error('Source reported an inconsistent size. Snapshot the file or fix Content-Length and retry.');
}
throw err;
} Prevention
- Pre-flight a HEAD request and pass an accurate contentLength to parseMedia.
- Use a byte-serving endpoint that honors Range headers strictly.
- Snapshot growing files to a stable URL/size before parsing.
- Ensure your custom readerInterface clamps each read to the declared length.
When it happens
Trigger: Reached after moov is not at the head and the parser re-fetches from endOfMdat onward. If the server returns more bytes than the original Content-Length (e.g. the source grew between requests, a proxy injected content, or contentLength was misreported by the caller) the offset will overshoot. Also reachable if endOfMdat is computed wrong, double-counting bytes.
Common situations: Live or append-only MP4s that grow between the HEAD and the range request. Misreported contentLength by a custom readerInterface. Proxies that decompress or transform the body. Range request that ignores Range headers and returns the whole file.
Related errors
- Expected box
- No moov box found
- Expected stsz box in trak box
- Expected stco box in trak box
- Expected stsc box in trak box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/321ffc4b3ea2fc88.
Report an issue: GitHub.