TeamNewPipe/NewPipe · error · IOException
moof found without mdat
Error message
moof found without mdat
What it means
During nextChunk(), a second moof (Movie Fragment) box is encountered while a previous moof is still pending (moof != null). In a well-formed fragmented MP4 each moof is immediately followed by its mdat; a second moof before the first's mdat means the structure is out of order or corrupt. The IOException signals the parser cannot reconcile the overlapping fragment headers.
Source
Thrown at app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java:194
public Mp4DashChunk getNextChunk(final boolean infoOnly) throws IOException {
final Mp4Track track = tracks[selectedTrack];
while (stream.available()) {
if (chunkZero) {
ensure(box);
if (!stream.available()) {
break;
}
box = readBox();
} else {
chunkZero = true;
}
switch (box.type) {
case ATOM_MOOF:
if (moof != null) {
throw new IOException("moof found without mdat");
}
moof = parseMoof(box, track.trak.tkhd.trackId);
if (moof.traf != null) {
if (hasFlag(moof.traf.trun.bFlags, 0x0001)) {
moof.traf.trun.dataOffset -= box.size + 8;
if (moof.traf.trun.dataOffset < 0) {
throw new IOException("trun box has wrong data offset, "
+ "points outside of concurrent mdat box");
}
}
if (moof.traf.trun.chunkSize < 1) {
if (hasFlag(moof.traf.tfhd.bFlags, 0x10)) {
moof.traf.trun.chunkSize = moof.traf.tfhd.defaultSampleSize
* moof.traf.trun.entryCount;View on GitHub (pinned to 9e8be09156)
Solutions
- Re-download the source file; box ordering corruption is almost always a damaged transfer.
- Re-mux the content with a known-good tool (ffmpeg/MP4Box) to fix the box layout.
- Validate the file with mp4info/MP4Box -info before feeding it to the reader.
- Catch IOException around nextChunk() and skip to the next valid fragment boundary if lossy recovery is acceptable.
Example fix
// before
while ((chunk = reader.getNextChunk(false)) != null) { ... } // throws mid-iteration
// after — tolerate a single corrupt fragment and continue
try {
while ((chunk = reader.getNextChunk(false)) != null) { ... }
} catch (IOException e) {
Log.w(TAG, "fragment ordering broken, stopping at " + e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-check can predict interleaved box order without full parsing; // instead, validate file integrity with MP4Box before demuxing. // MP4Box -info file.mp4 (exit non-zero or reports errors ⇒ do not feed to reader)
Type guard
// Not expressible as a type guard; this is runtime structural corruption.
// Use a boolean returned by a validation pass:
public static boolean boxOrderValid(Mp4DashReader r) { /* full scan */ return true; } Try / catch
try {
while ((chunk = reader.getNextChunk(false)) != null) { process(chunk); }
} catch (IOException e) {
if (e.getMessage().contains("moof found without mdat")) {
Log.w(TAG, "fragment ordering corrupt; stopping extraction here");
} else throw e;
} Prevention
- Validate the file with MP4Box/mp4info before demuxing.
- Re-download suspect segments rather than parsing damaged data.
- Do not manually reorder or edit MP4 boxes.
- Treat box-ordering errors as fatal for the current fragment, not the whole file.
When it happens
Trigger: A fragmented MP4 where moof boxes appear consecutively without an intervening mdat; a corrupt/malformed segment; a file that was truncated or had boxes reordered by a faulty muxer.
Common situations: Corrupt download where mdat bytes were lost but moof headers survived; a buggy server-side fragmenter; manual concatenation of fragments that dropped mdat payloads.
Related errors
- mdat found without moof
- 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/558f35439e179786.
Report an issue: GitHub.