nilaoda/N_m3u8DL-RE · error · Exception

TFDT version can only be 0 or 1

Error message

TFDT version can only be 0 or 1

What it means

While parsing a media segment for VTT cues, ExtractSub's 'tfdt' FullBox handler requires the Track Fragment Base Media Decode Time box version to be 0 or 1 (the only ISO BMFF-defined versions). Another version byte means the fragment is corrupt or was misparsed, so the decode-time base cannot be read.

Solutions

  1. Re-download the media segment; it is likely corrupt or truncated.
  2. Confirm the segment is a valid fMP4 fragment (check with MP4Box/Bento4 dump).
  3. Ensure the init segment passed to CheckInit matches these media segments (same stream).
  4. Catch the exception and skip the affected fragment's cues rather than failing the entire subtitle extraction.

Example fix

// before
var sub = MP4VttUtil.ExtractSub(segmentFiles, timescale); // throws on bad tfdt

// after
try
{
    var sub = MP4VttUtil.ExtractSub(segmentFiles, timescale);
}
catch (Exception ex) when (ex.Message.Contains("TFDT version"))
{
    Log.Warning("Media fragment has invalid tfdt box; skipping subtitle segment");
}
Defensive patterns

Strategy: try-catch

Try / catch

try { var sub = MP4VttUtil.ExtractSub(files, ts); }
catch (Exception ex) when (ex.Message.Contains("TFDT version"))
{ Log.Warning("Corrupt fragment (bad tfdt); skipping"); }

Prevention

When it happens

Trigger: Calling ExtractSub on a media segment whose moof/traf/tfdt full box has a version other than 0 or 1.

Common situations: Corrupt or truncated media fragment, a nonstandard muxer, or segment data that is not actually fMP4 (misaligned box parsing yields a bogus version byte).

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13). Data as JSON: /api/errors/4e0a3a614e8e94bc. Report an issue: GitHub.

Appendix: source

Thrown at src/N_m3u8DL-RE.Parser/Mp4/MP4VttUtil.cs:64

            bool sawTFDT = false;
            bool sawTRUN = false;
            bool sawMDAT = false;
            byte[]? rawPayload = null;
            ulong baseTime = 0;
            ulong defaultDuration = 0;
            List<Sample> presentations = [];


            // parse media
            new MP4Parser()
                .Box("moof", MP4Parser.Children)
                .Box("traf", MP4Parser.Children)
                .FullBox("tfdt", box =>
                {
                    sawTFDT = true;
                    if (box.Version is not (0 or 1))
                        throw new Exception("TFDT version can only be 0 or 1");
                    baseTime = MP4Parser.ParseTFDT(box.Reader, box.Version);
                })
                .FullBox("tfhd", box =>
                {
                    if (box.Flags == 1000)
                        throw new Exception("A TFHD box should have a valid flags value");
                    defaultDuration = MP4Parser.ParseTFHD(box.Reader, box.Flags).DefaultSampleDuration;
                })
                .FullBox("trun", box =>
                {
                    sawTRUN = true;
                    if (box.Version == 1000)
                        throw new Exception("A TRUN box should have a valid version value");
                    if (box.Flags == 1000)
                        throw new Exception("A TRUN box should have a valid flags value");
                    presentations = MP4Parser.ParseTRUN(box.Reader, box.Version, box.Flags).SampleData;
                })
                .Box("mdat", MP4Parser.AllData(data =>

View on GitHub (pinned to e113dee70c)