remotion-dev/remotion · error · Error
Could not find offset for byte offset ${offset}
Error message
Could not find offset for byte offset ${offset} What it means
Thrown at get-sample-from-block.ts:154 when `webmState.getTimestampOffsetForByteOffset(offset)` returns undefined. The WebmState maintains a map from cluster byte offsets to their timestamp base; a miss means the block being decoded belongs to a cluster whose offset was never registered during structure parsing.
Source
Thrown at packages/media-parser/src/containers/webm/get-sample-from-block.ts:154
}
const timecodeRelativeToCluster = iterator.getInt16();
const {keyframe} = parseBlockFlags(
iterator,
ebml.type === 'SimpleBlock'
? matroskaElements.SimpleBlock
: matroskaElements.Block,
);
const {codec, trackTimescale} = webmState.getTrackInfoByNumber(trackNumber);
const clusterOffset = webmState.getTimestampOffsetForByteOffset(offset);
const timescale = webmState.getTimescale();
if (clusterOffset === undefined) {
throw new Error('Could not find offset for byte offset ' + offset);
}
// https://github.com/hubblec4/Matroska-Chapters-Specs/blob/master/notes.md/#timestampscale
// The TimestampScale Element is used to calculate the Raw Timestamp of a Block. The timestamp is obtained by adding the Block's timestamp to the Cluster's Timestamp Element, and then multiplying that result by the TimestampScale. The result will be the Block's Raw Timestamp in nanoseconds.
const timecodeInNanoSeconds =
(timecodeRelativeToCluster + clusterOffset) *
timescale *
(trackTimescale ?? 1);
// Timecode should be in microseconds
const timecodeInMicroseconds = timecodeInNanoSeconds / 1000;
if (!codec) {
throw new Error(`Could not find codec for track ${trackNumber}`);
}
const remainingNow = ebml.value.length - iterator.counter.getOffset();
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Avoid seeking past unprocessed cluster boundaries — let the parser iterate sequentially, or seek only to offsets the controller has already reported.
- Ensure the full structure (all Cluster headers) is available before random access; for WebM this usually means a complete, non-streamed source.
- Re-mux the file so cluster timestamps are well-formed: `ffmpeg -i in.webm -c copy out.webm`.
- Catch and degrade gracefully — the timestamp cannot be recovered for this block.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await parseMedia({ src, fields: { samples: true }, controller });
} catch (err) {
if (err instanceof Error && err.message.startsWith('Could not find offset for byte offset')) {
// A block's byte offset is not in the cluster-timestamp map.
// Most often caused by seeking past unprocessed cluster headers.
console.warn('Cluster offset miss — avoid seeking past unprocessed clusters.');
return null;
}
throw err;
} Prevention
- Do not use a mediaParserController to seek forward past cluster headers the parser has not yet seen.
- Let the parser process clusters sequentially for WebM; random access requires a complete structure pass first.
- Re-mux files where Cluster Timecode elements are malformed so the offset map is populated correctly.
- For seek-heavy workflows, prefer MP4/MOV (sample tables) over WebM (linear clusters).
When it happens
Trigger: Decoding a Block/SimpleBlock at a byte `offset` that does not correspond to any Cluster element header the parser has seen. Happens when cluster boundaries are skipped, when the parser is used with a controller that seeks past clusters, or when the structure pass missed a Cluster due to truncation/corruption.
Common situations: Using a `mediaParserController` to seek into a region before its cluster header was parsed; forward-seeking past unprocessed clusters; files where Cluster Timecode elements are malformed so the offset map isn't populated.
Related errors
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/b4026ab4573a6815.
Report an issue: GitHub.