{"record":{"id":"35d72d62c6dff145","repo":"nilaoda/N_m3u8DL-RE","slug":"mdhd-version-can-only-be-0-or-1","errorCode":null,"errorMessage":"MDHD version can only be 0 or 1","messagePattern":"MDHD version can only be 0 or 1","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/N_m3u8DL-RE.Parser/Mp4/MP4VttUtil.cs","lineNumber":21,"sourceCode":"\nnamespace Mp4SubtitleParser;\n\npublic static class MP4VttUtil\n{\n    public static (bool, uint) CheckInit(byte[] data)\n    {\n        uint timescale = 0;\n        bool sawWVTT = false;\n\n        // parse init\n        new MP4Parser()\n            .Box(\"moov\", MP4Parser.Children)\n            .Box(\"trak\", MP4Parser.Children)\n            .Box(\"mdia\", MP4Parser.Children)\n            .FullBox(\"mdhd\", box =>\n            {\n                if (box.Version is not (0 or 1))\n                    throw new Exception(\"MDHD version can only be 0 or 1\");\n                timescale = MP4Parser.ParseMDHD(box.Reader, box.Version);\n            })\n            .Box(\"minf\", MP4Parser.Children)\n            .Box(\"stbl\", MP4Parser.Children)\n            .FullBox(\"stsd\", MP4Parser.SampleDescription)\n            .Box(\"wvtt\", _ => {\n                // A valid vtt init segment, though we have no actual subtitles yet.\n                sawWVTT = true;\n            })\n            .Parse(data);\n\n        return (sawWVTT, timescale);\n    }\n\n    public static WebVttSub ExtractSub(IEnumerable<string> files, uint timescale)\n    {\n        if (timescale == 0)\n            throw new Exception(\"Missing timescale for VTT content!\");","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/nilaoda/N_m3u8DL-RE/blob/e113dee70c924ee08dae5460624909b04d84cb76/src/N_m3u8DL-RE.Parser/Mp4/MP4VttUtil.cs#L3-L39","documentation":"MP4VttUtil.CheckInit builds an MP4Parser walk over the init segment and its 'mdhd' FullBox handler requires the mdhd version to be 0 or 1 (the only versions defined by ISO BMFF). Any other version byte indicates a corrupt or nonstandard track header, so CheckInit throws before a timescale can be read.","triggerScenarios":"Calling CheckInit on an MP4 init/segment whose moov/trak/mdia/mdhd full box has a version other than 0 or 1.","commonSituations":"Corrupt or truncated fMP4 init segment, a broken muxer emitting malformed mdhd boxes, or parsing a file that is not actually an MP4 (bytes misread shift the version field).","solutions":["Re-download or re-mux the init segment; the file data is likely corrupt.","Verify the file with MP4Box/Bento4 to inspect the mdhd box version.","Ensure you are passing the correct init segment bytes (not media data or a shifted offset) to CheckInit.","Catch the exception and report that the subtitle track init data is invalid."],"exampleFix":"// before\nvar (sawWvtt, timescale) = MP4VttUtil.CheckInit(initBytes);\n\n// after\ntry\n{\n    var (sawWvtt, timescale) = MP4VttUtil.CheckInit(initBytes);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"MDHD version\"))\n{\n    throw new Exception(\"Subtitle init segment is corrupt (invalid mdhd box)\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var (sawWvtt, ts) = MP4VttUtil.CheckInit(initBytes); }\ncatch (Exception ex) when (ex.Message.Contains(\"MDHD version\"))\n{ throw new InvalidDataException(\"Init segment mdhd box is corrupt\"); }","preventionTips":["Validate the init segment downloads (size/hash) before parsing.","Confirm the stream really is WebVTT-in-fMP4 before using MP4VttUtil.","Keep init and media segments from the same manifest/representation together."],"tags":["mp4","webvtt","parsing","subtitle"],"backgroundTag":"invalid-enum-value","analyzedSha":"e113dee70c924ee08dae5460624909b04d84cb76","analyzedAt":"2026-09-13T02:43:21.078Z","contentChangedAt":"2026-09-13T02:43:21.078Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}