nilaoda/N_m3u8DL-RE · error · Exception
A TRUN box should have a valid flags value
Error message
A TRUN box should have a valid flags value
What it means
In ExtractSub, the 'trun' box's flags field must be a valid value; 1000 is the sentinel MP4Parser assigns when the flags could not be read (truncated/malformed box). The library throws before calling ParseTRUN, because flags determine which optional per-sample fields follow and an invalid value would cause misparsing.
Solutions
- Re-download the segment and verify integrity (size or checksum).
- Validate the segment parses as complete MP4 boxes before feeding it to ExtractSub.
- Ensure the downloader honors Content-Length and does not write partial files.
- Use an MP4 box dumper to confirm the trun box flags (e.g. 0x000001/0x000100/0x000201).
Defensive patterns
Strategy: validation
Validate before calling
// ensure the segment is complete before extraction
if (dataSeg == null || dataSeg.Length < 8) throw new ArgumentException("segment too small");
// confirm trun flags are a known value via a box scan before ExtractSub Type guard
bool HasValidTrunFlags(byte[] seg) => Mp4BoxScanner.Find(seg, "trun") is { } b && b.Flags is 0x000001 or 0x000100 or 0x000201 or 0x000204; Try / catch
try { var subs = MP4VttUtil.ExtractSub(dataSeg, baseTime); }
catch (Exception ex) when (ex.Message.Contains("valid flags value")) {
logger.Warn("Malformed trun flags; re-fetching segment");
dataSeg = await reDownloadAsync(segmentUrl);
} Prevention
- Enforce Content-Length on segment downloads.
- Retry partial downloads from the CDN.
- Validate MP4 box structure before parsing.
- Keep a checksum of segments from the playlist where available.
When it happens
Trigger: ExtractSub is called on a segment whose 'trun' box is cut short so the 3-byte flags field cannot be read, yielding the sentinel value 1000.
Common situations: Truncated downloads over unstable connections; CDN edge nodes serving partial segments; concatenating or hex-editing segment data incorrectly.
Related errors
- A TRUN box should have a valid version value
- The samples do not fit evenly into the sample sizes given…
- VTT cues in mp4 with multiple MDAT are not currently…
- A required box is missing
- WVTT sample duration unknown, and no default found!
AI-assisted analysis of nilaoda/N_m3u8DL-RE@e113dee70c (2026-09-13).
Data as JSON: /api/errors/4865fd563c01e7d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/N_m3u8DL-RE.Parser/Mp4/MP4VttUtil.cs:79
{
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 =>
{
if (sawMDAT)
throw new Exception("VTT cues in mp4 with multiple MDAT are not currently supported");
sawMDAT = true;
rawPayload = data;
}))
.Parse(dataSeg,/* partialOkay= */ false);
if (!sawMDAT && !sawTFDT && !sawTRUN)
{
throw new Exception("A required box is missing");
}
var currentTime = baseTime;
var reader = new BinaryReader2(new MemoryStream(rawPayload!));View on GitHub (pinned to e113dee70c)