remotion-dev/remotion · error · Error

Expected tkhd box in trak box

Error message

Expected tkhd box in trak box

What it means

Thrown by getSamplePositionsFromTrack when getTkhdBox(trakBox) returns null. The tkhd (Track Header) box is mandatory in every trak per ISO/IEC 14496-12 and carries the trackId used to correlate moof fragments with their track. Without it the parser cannot compute sample positions for either fragmented or progressive paths.

Source

Thrown at packages/media-parser/src/containers/iso-base-media/get-sample-positions-from-track.ts:22

import {collectSamplePositionsFromTrak} from './collect-sample-positions-from-trak';
import type {TrexBox} from './moov/trex';
import type {TrakBox} from './trak/trak';
import {getTkhdBox} from './traversal';

export const getSamplePositionsFromTrack = ({
	trakBox,
	moofBoxes,
	moofComplete,
	trexBoxes,
}: {
	trakBox: TrakBox;
	moofBoxes: MoofBox[];
	moofComplete: boolean;
	trexBoxes: TrexBox[];
}): {samplePositions: SamplePosition[]; isComplete: boolean} => {
	const tkhdBox = getTkhdBox(trakBox);
	if (!tkhdBox) {
		throw new Error('Expected tkhd box in trak box');
	}

	if (moofBoxes.length > 0) {
		const {samplePositions} = collectSamplePositionsFromMoofBoxes({
			moofBoxes,
			tkhdBox,
			isComplete: moofComplete,
			trexBoxes,
		});

		return {
			samplePositions: samplePositions.map((s) => s.samples).flat(1),
			isComplete: moofComplete,
		};
	}

	return {
		samplePositions: collectSamplePositionsFromTrak(trakBox),

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Re-mux with ffmpeg `-c copy -movflags faststart` to rebuild tkhd and the full trak.
  2. Validate with `ffprobe` and reject malformed files upstream.
  3. Catch the error and report the file as unsupported.
  4. If authoring traks programmatically, always include a tkhd box as the first child of trak.

Example fix

// before
const { samplePositions } = getSamplePositionsFromTrack({ trakBox, moofBoxes, moofComplete, trexBoxes });

// after
try {
  const { samplePositions } = getSamplePositionsFromTrack({ trakBox, moofBoxes, moofComplete, trexBoxes });
} catch (err) {
  throw new Error(`Track is missing its header (tkhd). File is corrupt; re-mux with ffmpeg.`);
}
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

import type {TrakBox} from './trak/trak';
import type {TkhdBox} from './tkhd';
import {getTkhdBox} from './traversal';
function trakWithTkhd(trakBox: TrakBox): trakBox is TrakBox & { __tkhd: TkhdBox } {
  return getTkhdBox(trakBox) !== null;
}

Try / catch

try {
  const { samplePositions } = getSamplePositionsFromTrack({ trakBox, moofBoxes, moofComplete, trexBoxes });
} catch (err) {
  if (/Expected tkhd box/i.test(String(err?.message))) {
    throw new Error('trak is missing its tkhd header; file is corrupt, re-mux with ffmpeg.');
  }
  throw err;
}

Prevention

When it happens

Trigger: A trak box whose children do not include a tkhd-box, or whose tkhd was misparsed as a different box type. Reachable from both the moof-based and progressive branches of getSamplePositionsFromTrack since the check runs before branching.

Common situations: Corrupt moov/trak structure. Files from non-conformant muxers. Truncated files. Test fixtures with hand-crafted traks that omit tkhd.

Related errors


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