remotion-dev/remotion · error · Error

expected 0 bytes ${bytesRemaining}

Error message

expected 0 bytes ${bytesRemaining}

What it means

After parsing the TFHD (Track Fragment Header) box fields conditionally based on flags (baseDataOffset, sample description index, default durations/sizes/flags), the parser asserts zero bytes remaining. Non-zero bytesRemaining means an unrecognized flag bit indicated extra fields the parser did not consume, or the box has trailing/padding data.

Source

Thrown at packages/media-parser/src/containers/iso-base-media/tfhd.ts:53

		? iterator.getUint32()
		: 0;

	const defaultSampleDurationPresent = flags & 0x08;
	const defaultSampleDuration = defaultSampleDurationPresent
		? iterator.getUint32()
		: 0;

	const defaultSampleSizePresent = flags & 0x10;
	const defaultSampleSize = defaultSampleSizePresent ? iterator.getUint32() : 0;

	const defaultSampleFlagsPresent = flags & 0x20;
	const defaultSampleFlags = defaultSampleFlagsPresent
		? iterator.getUint32()
		: 0;

	const bytesRemaining = size - (iterator.counter.getOffset() - offset);
	if (bytesRemaining !== 0) {
		throw new Error('expected 0 bytes ' + bytesRemaining);
	}

	return {
		type: 'tfhd-box',
		version,
		trackId,
		baseDataOffset,
		baseSampleDescriptionIndex,
		defaultSampleDuration,
		defaultSampleSize,
		defaultSampleFlags,
	};
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Dump the tfhd box: `mp4dump input.mp4 | grep -A5 tfhd` to see the flags and size.
  2. Re-mux: `ffmpeg -i input.mp4 -c copy -f mp4 -movflags +faststart remuxed.mp4`.
  3. For DASH/HLS, re-fetch the offending segment.
  4. Report upstream if a standard tfhd flag bit is genuinely unsupported.

Example fix

// before: tfhd with unsupported flag bit leaves trailing bytes
ffmpeg -i segment.m4s -c copy remuxed.mp4
// after: tfhd bytesRemaining === 0
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify tfhd flag bits are all handled before parsing
// Known handled flags: 0x01 (baseDataOffset), 0x02 (sampleDescIndex), 0x08 (defaultDuration), 0x10 (defaultSize), 0x20 (defaultFlags)
const HANDLED_TFHD_FLAGS = 0x01 | 0x02 | 0x08 | 0x10 | 0x20;
function hasUnhandledTfhdFlags(flags: number): boolean {
  return (flags & ~HANDLED_TFHD_FLAGS) !== 0;
}

Try / catch

try {
  await parseMedia({src, fields: {dimensions: true}});
} catch (err) {
  if (err instanceof Error && err.message.startsWith('expected 0 bytes') && /* tfhd context */) {
    // tfhd has unhandled flag bit or trailing bytes; re-mux
  } else throw err;
}

Prevention

When it happens

Trigger: The tfhd flags field has a bit set that the parser does not handle, leaving bytes unconsumed; or the declared size includes data the parser does not expect.

Common situations: Fragmented MP4 from DASH/HLS with proprietary or newer-spec tfhd flag bits; corrupt traf boxes; or files from non-conformant live packagers.

Related errors


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