remotion-dev/remotion · error · Error
Expected stsc box in trak box
Error message
Expected stsc box in trak box
What it means
Thrown by collectSamplePositionsFromTrak when a trak box lacks an stsc (Sample-to-Chunk) box. The stsc table maps each chunk to the number of samples it contains plus their default size delta, which is required to translate sample indices into byte ranges. ISO/IEC 14496-12 mandates stsc inside stbl for any sample table that is actually populated.
Source
Thrown at packages/media-parser/src/containers/iso-base-media/collect-sample-positions-from-trak.ts:42
}
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,
stssBox,
sttsBox,
cttsBox,
});View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Re-mux with `ffmpeg -i input.mp4 -c copy -movflags faststart fixed.mp4` to rebuild the sample tables.
- Validate with `ffprobe` and reject the file upstream if the sample table is incomplete.
- Wrap parse/seek calls in try/catch and degrade gracefully (skip seeking, treat as non-seekable stream).
- If you produce the files, switch muxer settings to a conformant stbl layout.
Example fix
// before
const positions = collectSamplePositionsFromTrak(trakBox);
// after
let positions;
try {
positions = collectSamplePositionsFromTrak(trakBox);
} catch (err) {
return { seekable: false, reason: 'incomplete-sample-table' };
} Defensive patterns
Strategy: try-catch
Validate before calling
import {execFileSync} from 'node:child_process';
function isSampleTableComplete(file: string): boolean {
try {
execFileSync('ffprobe', ['-v', 'error', '-count_frames', '-select_streams', 'v:0', '-show_entries', 'stream=nb_read_frames', '-of', 'csv', file], {encoding: 'utf8'});
return true;
} catch { return false; }
} Type guard
import type {TrakBox} from './trak/trak';
import {getStscBox} from './traversal';
function trakHasStsc(trakBox: TrakBox): boolean {
return getStscBox(trakBox) !== null;
} Try / catch
try {
const positions = collectSamplePositionsFromTrak(trakBox);
} catch (err) {
if (/Expected stsc box/i.test(String(err?.message))) {
return { seekable: false, reason: 'missing-stsc' };
}
throw err;
} Prevention
- Treat any 'Expected <box> box in trak box' error as a corrupt-file signal and stop parsing that asset.
- Standardize on a faststart re-mux step in your ingestion pipeline.
- Surface a single, consistent 'unsupported file' message rather than raw box names to end users.
- Log the failing file's hash so you can correlate recurring bad assets.
When it happens
Trigger: A progressive MP4 trak whose stbl has no stsc child. Common with empty/placeholder traks, severely truncated files, or non-conformant muxers. Also reachable if the traversal that fetches stsc returns null because the box is present but parsed as a different type due to a size/encoding bug.
Common situations: Truncated downloads where the moov is at the head and the stbl got cut off. Files authored by research/specialized tools that write stsz/stco but skip stsc. Damaged files that survived a copy but lost a box boundary.
Related errors
- Expected stsz box in trak box
- Expected stco box in trak box
- Expected stts box in trak box
- Expected timescale and duration in trak box
- Expected box
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/261d7ab9c2bc69e4.
Report an issue: GitHub.