TeamNewPipe/NewPipe · warning · EOFException
EOF reached while reading a sample
Error message
EOF reached while reading a sample
What it means
Mp4DashReader.Mp4DashChunk.nextSample() allocates a byte[] sized to sample.info.sampleSize and reads that many bytes from the chunk data. If data.read() returns fewer bytes than sampleSize, the sample is incomplete and an EOFException is thrown. This protects against a chunk whose mdat payload is shorter than the sample table declares.
Source
Thrown at app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java:932
return null;
}
return moof.traf.trun.getAbsoluteEntry(i++, moof.traf.tfhd);
}
public Mp4DashSample getNextSample() throws IOException {
if (data == null) {
throw new IllegalStateException("This chunk has info only");
}
if (i >= moof.traf.trun.entryCount) {
return null;
}
final Mp4DashSample sample = new Mp4DashSample();
sample.info = moof.traf.trun.getAbsoluteEntry(i++, moof.traf.tfhd);
sample.data = new byte[sample.info.sampleSize];
if (data.read(sample.data) != sample.info.sampleSize) {
throw new EOFException("EOF reached while reading a sample");
}
return sample;
}
}
public static class Mp4DashSample {
public TrunEntry info;
public byte[] data;
}
}
View on GitHub (pinned to 9e8be09156)
Solutions
- Re-download the segment; the mdat payload is shorter than the sample table.
- Verify the moof+mdat pair is fully downloaded before iterating samples.
- Catch EOFException during sample iteration and stop gracefully (partial audio extraction may still be usable).
- If muxing, ensure each trun sample size sums exactly to the mdat content length.
Example fix
// before
while ((sample = chunk.nextSample()) != null) { write(sample); } // throws on last sample
// after — tolerate truncation on the final sample
try {
while ((sample = chunk.nextSample()) != null) { write(sample); }
} catch (EOFException e) {
Log.w(TAG, "chunk truncated at final sample: " + e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before iterating samples, confirm the chunk's mdat covers the declared sample sizes.
long declared = 0;
for (int i = 0; i < chunk.moof.traf.trun.entryCount; i++)
declared += chunk.moof.traf.trun.getAbsoluteEntry(i, chunk.moof.traf.tfhd).sampleSize;
if (declared > chunk.data.available()) {
throw new IOException("mdat shorter than declared sample sizes");
} Type guard
public static boolean chunkPayloadComplete(Mp4DashChunk chunk, long declaredBytes) {
return chunk.data != null && chunk.data.available() >= declaredBytes;
} Try / catch
try {
while ((sample = chunk.nextSample()) != null) { write(sample.data); }
} catch (EOFException e) {
// last sample truncated — keep already-extracted samples, stop gracefully
Log.w(TAG, "chunk ended early: " + e.getMessage());
} Prevention
- Verify the moof+mdat pair downloaded fully before iterating samples.
- Sum trun sample sizes and compare to mdat length before reading.
- Tolerate EOF on the final sample when partial extraction is acceptable.
- Re-download truncated segments for complete extraction.
When it happens
Trigger: Iterating samples via nextSample() when the mdat payload for the current chunk contains fewer bytes than the trun sample table claims (sampleSize per entry). A truncated mdat or an over-declared sample size.
Common situations: A truncated media segment download; a moof whose trun sample sizes don't match the mdat length; a re-encoded stream whose segment boundaries shifted; a partial download resumed from the wrong offset.
Related errors
- Truncated stream, missing {} bytes
- EOF reached in box: type=%s offset=%s size=%s
- Not a MPEG-4 DASH container, major brand is not 'dash' or 'i
- The provided Mp4 doesn't have the 'moov' box
- moof found without mdat
AI-assisted analysis of TeamNewPipe/NewPipe@9e8be09156 (2026-08-14).
Data as JSON: /api/errors/c3f77cde18f0ed9b.
Report an issue: GitHub.