TeamNewPipe/NewPipe · error · IOException

The provided Mp4 doesn't have the 'moov' box

Error message

The provided Mp4 doesn't have the 'moov' box

What it means

After Mp4DashReader.parse() accepts the ftyp brand and loops reading boxes until it hits the first moof, it requires that a moov box was encountered in that initial sequence. moov holds track metadata (tkhd, trex, etc.); if none was parsed, the file cannot be demuxed and an IOException is thrown. A DASH init segment normally carries the moov; its absence means the file is incomplete or is a media segment without its init segment.

Source

Thrown at app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java:109

        Moov moov = null;
        int i;

        while (box.type != ATOM_MOOF) {
            ensure(box);
            box = readBox();

            switch (box.type) {
                case ATOM_MOOV:
                    moov = parseMoov(box);
                    break;
                case ATOM_SIDX:
                case ATOM_MFRA:
                    break;
            }
        }

        if (moov == null) {
            throw new IOException("The provided Mp4 doesn't have the 'moov' box");
        }

        tracks = new Mp4Track[moov.trak.length];

        for (i = 0; i < tracks.length; i++) {
            tracks[i] = new Mp4Track();
            tracks[i].trak = moov.trak[i];

            if (moov.mvexTrex != null) {
                for (final Trex mvexTrex : moov.mvexTrex) {
                    if (tracks[i].trak.tkhd.trackId == mvexTrex.trackId) {
                        tracks[i].trex = mvexTrex;
                    }
                }
            }

            switch (moov.trak[i].mdia.hdlr.subType) {
                case HANDLER_VIDE:

View on GitHub (pinned to 9e8be09156)

Solutions

  1. Ensure the init segment (containing moov) is prepended before parsing — fetch and concatenate the DASH initialization URL first.
  2. Validate the source is a complete self-init fragmented MP4, not a bare media segment.
  3. If building the input from multiple range requests, confirm the moov range was successfully downloaded (check HTTP 200 and full byte count).
  4. Re-fetch the stream from the start to include the moov box.

Example fix

// before — parsing a media segment without init
new Mp4DashReader(mediaSegmentStream).parse(); // IOException: no moov

// after — prepend the init segment (which carries moov)
SharpStream combined = new ConcatStream(initSegmentStream, mediaSegmentStream);
new Mp4DashReader(combined).parse();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the init segment (carrying moov) is concatenated before the media segment.
if (!hasInitSegment) {
    throw new IllegalStateException("prepend the DASH init segment before parsing");
}
new Mp4DashReader(concatenatedStream).parse();

Type guard

// After a shallow scan, confirm a moov box exists in the byte range to be parsed.
public static boolean containsMoovBox(SharpStream s, long scanLimit) throws IOException {
    long pos = s.position();
    try {
        long end = Math.min(scanLimit, s.isLengthKnown() ? s.length() : scanLimit);
        while (s.position() < end) {
            int size = readInt(s); int type = readInt(s);
            if (type == 0x6D6F6F76 /*moov*/) return true;
            s.skip(size - 8);
        }
        return false;
    } finally { s.seek(pos); }
}

Try / catch

try {
    reader.parse();
} catch (IOException e) {
    if (e.getMessage().contains("moov")) {
        // missing init segment — fetch and prepend it, then retry once with a fresh reader
        fetchAndPrependInitSegment();
        new Mp4DashReader(combinedStream).parse();
    } else throw e;
}

Prevention

When it happens

Trigger: Parsing a fragmented MP4 that contains moof/mdat boxes but no moov — e.g. an MP4 'media segment' (moof+mdat) streamed without its accompanying initialization segment (moov). Also a file whose moov sits after the first moof in an unexpected layout this reader does not scan past.

Common situations: Downloading only the media segments of a DASH manifest and concatenating them without the init segment; a live stream where the init segment was missed; a download manager that dropped the first chunk.

Related errors


AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14). Data as JSON: /api/errors/44485447df986efb. Report an issue: GitHub.