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
- Verify with ffprobe that the file is a valid Matroska/WebM with a Segment.
- Re-download or re-mux: ffmpeg -i in.mkv -c copy out.mkv.
- Sniff the EBML magic (0x1A45DFA3) before parsing.
- 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
- Sniff the EBML magic before parsing.
- Validate MKV/WebM with ffprobe (it must report a Segment).
- Don't parse live/truncated streams expecting a full Segment.
- Use Mediabunny.
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
- No tracks segment
- Expected av1 private data to be version 1
- Expected av1 private data to be version 1, got ${version}
- Expected vorbis private data version 2
- Error parsing vorbis codec private
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/648dea5208cfb773.
Report an issue: GitHub.