{"record":{"id":"7c0fa8f52911833d","repo":"remotion-dev/remotion","slug":"expected-stts-box-to-be-size-bytes-but-was-b","errorCode":null,"errorMessage":"Expected stts box to be ${size} bytes, but was ${bytesUsed} bytes","messagePattern":"Expected stts box to be (.+?) bytes, but was (.+?) bytes","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/media-parser/src/containers/iso-base-media/stsd/stts.ts","lineNumber":53,"sourceCode":"\n\tconst sampleDistributions: SampleDistribution[] = [];\n\n\t// entries\n\tfor (let i = 0; i < entryCount; i++) {\n\t\tconst sampleCount = data.getUint32();\n\t\tconst sampleDelta = data.getUint32();\n\n\t\tconst sampleDistribution: SampleDistribution = {\n\t\t\tsampleCount,\n\t\t\tsampleDelta,\n\t\t};\n\t\tsampleDistributions.push(sampleDistribution);\n\t}\n\n\tconst bytesUsed = data.counter.getOffset() - initialOffset + initialCounter;\n\n\tif (bytesUsed !== size) {\n\t\tthrow new Error(\n\t\t\t`Expected stts box to be ${size} bytes, but was ${bytesUsed} bytes`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: 'stts-box',\n\t\tsampleDistribution: sampleDistributions,\n\t};\n};\n","sourceCodeStart":35,"sourceCodeEnd":63,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-parser/src/containers/iso-base-media/stsd/stts.ts#L35-L63","documentation":"After parsing all STTS entries, the parser checks that the bytes consumed exactly equal the declared box size. A mismatch means either entryCount was wrong, entries were mis-sized, or trailing garbage exists in the box. This is a structural integrity check that catches subtle corruption and cursor-drift bugs.","triggerScenarios":"The bytesUsed (current offset minus initial offset plus counter) does not equal the declared stts box size after reading entryCount entries.","commonSituations":"Files where entryCount does not match the actual number of entries that fit, padding/trailing bytes inside the stts box, or upstream cursor desync reducing available bytes.","solutions":["Inspect the stts box with `mp4dump input.mp4` or `mp4box -dnal input.mp4` to see declared size vs entry count.","Re-mux: `ffmpeg -i input.mp4 -c copy remuxed.mp4`.","Transcode to fully regenerate timing tables: `ffmpeg -i input.mp4 -c:v libx264 -c:a aac out.mp4`.","If this is a fragmented MP4 from a live source, the segment may have been cut mid-write."],"exampleFix":"// before: stts size header lies about entry count\nffmpeg -i corrupt.mp4 -c copy remuxed.mp4\n// after: stts bytesUsed matches declared size","handlingStrategy":"try-catch","validationCode":"// Verify stts box size vs entryCount*8+header with mp4dump before parsing\n// declared_size should equal 8 (box header) + 4 (version/flags) + 4 (entryCount) + entryCount*8","typeGuard":null,"tryCatchPattern":"try {\n  await parseMedia({src, fields: {dimensions: true}});\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Expected stts box to be')) {\n    // size/count mismatch; re-mux or transcode\n  } else throw err;\n}","preventionTips":["Re-mux with ffmpeg to rebuild the stts box consistently.","Transcode to regenerate timing tables if re-mux fails.","Use mp4dump to inspect stts size/count for untrusted inputs."],"tags":["media-parser","isobmff","stts-box","corrupt-file","integrity-check","mp4"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}