remotion-dev/remotion · error · Error

Expected stco box in trak box

Error message

Expected stco box in trak box

What it means

Thrown by collectSamplePositionsFromTrak when a trak box lacks an stco (Sample-to-Chunk Offset / 64-bit co64 variant) box. The stco box maps each chunk to its absolute file byte offset, which is mandatory for computing where samples live in a non-fragmented (progressive) MP4. Without it the parser cannot build sample positions for seeking or track construction. ISOBMFF/MP4 spec (ISO/IEC 14496-12) requires stco or co64 in every well-formed stbl/minf/stbl hierarchy.

Source

Thrown at packages/media-parser/src/containers/iso-base-media/collect-sample-positions-from-trak.ts:38

		return getGroupedSamplesPositionsFromMp4({
			trakBox,
			bigEndian: shouldGroupSamples.bigEndian,
		});
	}

	const stszBox = getStszBox(trakBox);
	const stcoBox = getStcoBox(trakBox);
	const stscBox = getStscBox(trakBox);
	const stssBox = getStssBox(trakBox);
	const sttsBox = getSttsBox(trakBox);
	const cttsBox = getCttsBox(trakBox);

	if (!stszBox) {
		throw new Error('Expected stsz box in trak box');
	}

	if (!stcoBox) {
		throw new Error('Expected stco box in trak box');
	}

	if (!stscBox) {
		throw new Error('Expected stsc box in trak box');
	}

	if (!sttsBox) {
		throw new Error('Expected stts box in trak box');
	}

	if (!timescaleAndDuration) {
		throw new Error('Expected timescale and duration in trak box');
	}

	const samplePositions = getSamplePositions({
		stcoBox,
		stscBox,
		stszBox,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Re-mux the source with a recent ffmpeg build using `ffmpeg -i input.mp4 -c copy -movflags faststart remuxed.mp4` to regenerate a complete stbl with stco.
  2. Verify the file integrity with `ffprobe -v error -show_streams input.mp4`; if ffprobe reports a malformed track, treat the file as unsupported.
  3. If you control the muxing pipeline, ensure it emits a 32-bit stco (or confirm the parser build you target unifies co64).
  4. Guard the parse call in a try/catch and surface a user-facing 'unsupported/corrupt file' message rather than crashing.

Example fix

// before
const positions = collectSamplePositionsFromTrak(trakBox);

// after
try {
  const positions = collectSamplePositionsFromTrak(trakBox);
} catch (err) {
  throw new Error(`Cannot seek this MP4: ${err instanceof Error ? err.message : err}. Re-mux the file with ffmpeg -movflags faststart.`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe the file's sample table completeness before parsing deeply
import {execFileSync} from 'node:child_process';
function hasStco(file: string): boolean {
  const out = execFileSync('ffprobe', ['-v', 'error', '-select_streams', 'v:0', '-show_entries', 'stream=index', '-of', 'json', file], {encoding: 'utf8'});
  return !/error|invalid/i.test(out);
}

Type guard

import type {TrakBox} from './trak/trak';
import {getStcoBox} from './traversal';
function trakHasStco(trakBox: TrakBox): boolean {
  return getStcoBox(trakBox) !== null;
}

Try / catch

try {
  const positions = collectSamplePositionsFromTrak(trakBox);
} catch (err) {
  if (/Expected stco box/i.test(String(err?.message))) {
    return { seekable: false, reason: 'missing-stco' };
  }
  throw err;
}

Prevention

When it happens

Trigger: Called when the media-parser walks a progressive (non-fragmented) MP4 trak whose stbl is missing the stco child. This happens if the file was written by a tool that omits stco, if the trak is a hint/track that uses a different offset scheme, or if the box was stripped/truncated by a transcode remux that wrote co64 instead and the parser's traversal does not fold co64 into getStcoBox for this code path.

Common situations: Corrupt or half-written MP4 files (interrupted download, truncated upload). Files produced by non-standard muxers (some HLS packagers, older ffmpeg profiles, screen recorders). Files where the offset table is stored as co64 (64-bit) rather than stco (32-bit) and the parser version does not unify them.

Related errors


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