remotion-dev/remotion · error · Error

No main segment

Error message

No main segment

What it means

getTracksFromMatroska walks the parsed EBML box list looking for a top-level Matroska Segment element (ID 0x18538067). If getMainSegment returns null it throws 'No main segment' — the file is not a complete/valid Matroska or WebM, or the Segment has not yet been parsed. This runs while resolving tracks.

Source

Thrown at packages/media-parser/src/containers/webm/get-ready-tracks.ts:26

} from './make-track';
import {getMainSegment, getTracksSegment} from './traversal';

export type ResolvedAndUnresolvedTracks = {
	resolved: MediaParserTrack[];
	missingInfo: MediaParserTrack[];
};

export const getTracksFromMatroska = ({
	structureState,
	webmState,
}: {
	structureState: StructureState;
	webmState: WebmState;
}): ResolvedAndUnresolvedTracks => {
	const structure = structureState.getMatroskaStructure();
	const mainSegment = getMainSegment(structure.boxes);
	if (!mainSegment) {
		throw new Error('No main segment');
	}

	const tracksSegment = getTracksSegment(mainSegment);

	if (!tracksSegment) {
		throw new Error('No tracks segment');
	}

	const resolvedTracks: MediaParserTrack[] = [];
	const missingInfo: MediaParserTrack[] = [];

	for (const trackEntrySegment of tracksSegment.value) {
		if (trackEntrySegment.type === 'Crc32') {
			continue;
		}

		if (trackEntrySegment.type !== 'TrackEntry') {
			throw new Error('Expected track entry segment');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Verify with ffprobe that the file is a valid Matroska/WebM with a Segment.
  2. Re-download or re-mux: ffmpeg -i in.mkv -c copy out.mkv.
  3. Sniff the EBML magic (0x1A45DFA3) before parsing.
  4. Use Mediabunny; try/catch parseMedia().

Example fix

# validate then re-mux
ffprobe -v error in.mkv && ffmpeg -i in.mkv -c copy out.mkv

await parseMedia({ src: 'out.mkv' });
Defensive patterns

Strategy: validation

Validate before calling

// sniff the EBML magic before parsing a Matroska/WebM file
import { promises as fs } from 'fs';
const fd = await fs.open(path, 'r');
const buf = Buffer.alloc(4);
await fd.read(buf, 0, 4, 0);
await fd.close();
// EBML magic = 0x1A 0x45 0xDF 0xA3
const isMatroska = buf[0] === 0x1a && buf[1] === 0x45 && buf[2] === 0xdf && buf[3] === 0xa3;
if (!isMatroska) throw new Error('not a Matroska/WebM file');

Type guard

const isMatroska = (head: Uint8Array) =>
  head.length >= 4 && head[0] === 0x1a && head[1] === 0x45 && head[2] === 0xdf && head[3] === 0xa3;

Try / catch

try {
  await parseMedia({ src });
} catch (err) {
  if (err instanceof Error && /No main segment/.test(err.message)) {
    // truncated/invalid Matroska — re-mux or skip
  } else throw err;
}

Prevention

When it happens

Trigger: parseMedia() on a .mkv/.webm that has no top-level Segment: truncated/empty file, a header-only stream, a live stream parsed before the Segment arrived, or a non-Matroska file misrouted to the WebM parser.

Common situations: Truncated download; live stream read too early; corrupted EBML; wrong container sniff; empty file.

Related errors


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