TeamNewPipe/NewPipe · error · IOException
mdat found without moof
Error message
mdat found without moof
What it means
In nextChunk(), an mdat (Media Data) box is found while moof is null. Fragmented MP4 requires every mdat to be preceded by its describing moof; an mdat with no preceding fragment header has no sample table and cannot be decoded. The IOException stops the parse rather than reading uninterpretable bytes.
Source
Thrown at app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java:228
if (hasFlag(moof.traf.tfhd.bFlags, 0x10)) {
moof.traf.trun.chunkSize = moof.traf.tfhd.defaultSampleSize
* moof.traf.trun.entryCount;
} else {
moof.traf.trun.chunkSize = (int) (box.size - 8);
}
}
if (!hasFlag(moof.traf.trun.bFlags, 0x900)
&& moof.traf.trun.chunkDuration == 0) {
if (hasFlag(moof.traf.tfhd.bFlags, 0x20)) {
moof.traf.trun.chunkDuration = moof.traf.tfhd.defaultSampleDuration
* moof.traf.trun.entryCount;
}
}
}
break;
case ATOM_MDAT:
if (moof == null) {
throw new IOException("mdat found without moof");
}
if (moof.traf == null) {
moof = null;
continue; // find another chunk
}
final Mp4DashChunk chunk = new Mp4DashChunk();
chunk.moof = moof;
if (!infoOnly) {
chunk.data = stream.getView(moof.traf.trun.chunkSize);
}
moof = null;
stream.skipBytes(chunk.moof.traf.trun.dataOffset);
return chunk;
default:View on GitHub (pinned to 9e8be09156)
Solutions
- Confirm the input is a fragmented MP4 with correct moof→mdat ordering (re-download if suspect).
- Pre-validate the ftyp brand (error 21) since a progressive MP4 will hit this after the brand check.
- Re-mux the source with a conformant fragmenter.
- Ensure range requests include the moof that precedes each mdat.
Example fix
// before — feeding a progressive MP4 to the DASH reader new Mp4DashReader(progressiveStream).parse(); // mdat before moof → IOException // after — use the fragmented/DASH source for this reader new Mp4DashReader(fragmentedStream).parse();
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the input is fragmented (moof precedes mdat) via a shallow scan.
public static boolean isFragmented(SharpStream s, long scanLimit) throws IOException {
long pos = s.position();
try {
boolean sawMoof = false;
while (s.position() < scanLimit) {
int size = readInt(s); int type = readInt(s);
if (type == 0x6D6F6F66 /*moof*/) sawMoof = true;
if (type == 0x6D646174 /*mdat*/) return sawMoof; // valid only if moof seen first
s.skip(size - 8);
}
return false;
} finally { s.seek(pos); }
} Type guard
public static boolean isDashFragmentedMp4(byte[] ftypHead) {
if (ftypHead.length < 8) return false;
int brand = ((ftypHead[4]&0xFF)<<24)|((ftypHead[5]&0xFF)<<16)|((ftypHead[6]&0xFF)<<8)|(ftypHead[7]&0xFF);
return brand == 0x64617368 || brand == 0x69736F35;
} Try / catch
try {
reader.parse();
} catch (IOException e) {
if (e.getMessage().contains("mdat found without moof")) {
// progressive MP4 or corrupt segment — switch source
selectFragmentedDashSource();
} else throw e;
} Prevention
- Feed only fragmented DASH MP4 to Mp4DashReader.
- Sniff the ftyp brand and scan for moof-before-mdat before parsing.
- Re-download segments that arrive out of order or truncated.
- Keep progressive MP4 paths separate from DASH paths.
When it happens
Trigger: A fragmented MP4 whose box order places mdat before moof, or a file with an orphan mdat (e.g. a progressive MP4's mdat leaking into DASH parsing). Also a partially over-written segment where moof was lost but mdat survived.
Common situations: Wrong file type fed to the DASH reader (a progressive MP4 has mdat early, no moof); a corrupted segment missing its moof; a download that started mid-file skipping the moof header.
Related errors
- moof found without mdat
- Not a MPEG-4 DASH container, major brand is not 'dash' or 'i
- The provided Mp4 doesn't have the 'moov' box
- trun box has wrong data offset, points outside of concurrent
- parser go beyond limits of the box. type=%s offset=%s size=%
AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14).
Data as JSON: /api/errors/8c57abbb2ced819c.
Report an issue: GitHub.