remotion-dev/remotion · error · Error

Reached the end of the file even though a seek was requested

Error message

Reached the end of the file even though a seek was requested. This is likely a bug in the parser. You can report this at https://remotion.dev/report and we will fix it as soon as possible.

What it means

After the final sample is observed, parseLoop checks whether a seek is still pending (controller seekSignal). If so it calls workOnSeekRequest; if the seek is STILL pending afterward, the parser throws because seeking past EOF is unrecoverable and indicates an internal bug. The message directs users to report it.

Source

Thrown at packages/media-parser/src/parse-loop.ts:191

		if (!didProgress) {
			iterationWithThisOffset++;
		} else {
			iterationWithThisOffset = 0;
		}
	}

	state.samplesObserved.setLastSampleObserved();
	await state.callbacks.callTracksDoneCallback();

	// After the last sample, you might queue a last seek again.
	if (state.controller._internals.seekSignal.getSeek() !== null) {
		Log.verbose(
			state.logLevel,
			'Reached end of samples, but there is a pending seek. Trying to seek...',
		);
		await workOnSeekRequest(getWorkOnSeekRequestOptions(state));
		if (state.controller._internals.seekSignal.getSeek() !== null) {
			throw new Error(
				'Reached the end of the file even though a seek was requested. This is likely a bug in the parser. You can report this at https://remotion.dev/report and we will fix it as soon as possible.',
			);
		}

		await parseLoop({
			onError,
			throttledState,
			state,
		});
	}
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Report the file at https://remotion.dev/report.
  2. Re-download the source fully (verify size/checksum) in case it was truncated.
  3. Re-mux/re-encode to rebuild sample tables (`ffmpeg -i in -c copy out.mp4`).
  4. If you are issuing manual seeks via the controller, ensure the seek target is within the media duration.

Example fix

// before
await parseMedia({src: truncated, fields: {durationInSeconds: true}});

// after: re-fetch fully + re-mux
// curl -o full.mp4 <url>  (verify size matches Content-Length)
// ffmpeg -i full.mp4 -c copy repaired.mp4
await parseMedia({src: 'repaired.mp4', fields: {durationInSeconds: true}});
Defensive patterns

Strategy: try-catch

Validate before calling

import {execFileSync} from 'node:child_process';
function isComplete(path: string): boolean {
  try { execFileSync('ffprobe', ['-v','error', path], {stdio:'pipe'}); return true; } catch { return false; }
}

Try / catch

try {
  await parseMedia({src, fields: {durationInSeconds: true}});
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Reached the end of the file')) {
    // re-download fully / re-mux; otherwise report upstream
    throw new Error('Asset appears truncated or has a corrupt sample table');
  }
  throw e;
}

Prevention

When it happens

Trigger: A seek request was queued (user-initiated or parser-internal) that could not be satisfied before the file ended — e.g. a malformed sample table pointing beyond EOF, or a seek computed against an incorrect content length. Defensive guard, not typically user-fixable.

Common situations: Corrupt MP4/Matroska sample tables, truncated downloads where the tail is missing, or parser bugs computing seek targets. Rare in well-formed media.

Related errors


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