{"record":{"id":"c3f77cde18f0ed9b","repo":"TeamNewPipe/NewPipe","slug":"eof-reached-while-reading-a-sample","errorCode":null,"errorMessage":"EOF reached while reading a sample","messagePattern":"EOF reached while reading a sample","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"warning","filePath":"app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java","lineNumber":932,"sourceCode":"                return null;\n            }\n            return moof.traf.trun.getAbsoluteEntry(i++, moof.traf.tfhd);\n        }\n\n        public Mp4DashSample getNextSample() throws IOException {\n            if (data == null) {\n                throw new IllegalStateException(\"This chunk has info only\");\n            }\n            if (i >= moof.traf.trun.entryCount) {\n                return null;\n            }\n\n            final Mp4DashSample sample = new Mp4DashSample();\n            sample.info = moof.traf.trun.getAbsoluteEntry(i++, moof.traf.tfhd);\n            sample.data = new byte[sample.info.sampleSize];\n\n            if (data.read(sample.data) != sample.info.sampleSize) {\n                throw new EOFException(\"EOF reached while reading a sample\");\n            }\n\n            return sample;\n        }\n    }\n\n    public static class Mp4DashSample {\n        public TrunEntry info;\n        public byte[] data;\n    }\n}\n","sourceCodeStart":914,"sourceCodeEnd":944,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/org/schabi/newpipe/streams/Mp4DashReader.java#L914-L944","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nwhile ((sample = chunk.nextSample()) != null) { write(sample); } // throws on last sample\n\n// after — tolerate truncation on the final sample\ntry {\n    while ((sample = chunk.nextSample()) != null) { write(sample); }\n} catch (EOFException e) {\n    Log.w(TAG, \"chunk truncated at final sample: \" + e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"// Before iterating samples, confirm the chunk's mdat covers the declared sample sizes.\nlong declared = 0;\nfor (int i = 0; i < chunk.moof.traf.trun.entryCount; i++)\n    declared += chunk.moof.traf.trun.getAbsoluteEntry(i, chunk.moof.traf.tfhd).sampleSize;\nif (declared > chunk.data.available()) {\n    throw new IOException(\"mdat shorter than declared sample sizes\");\n}","typeGuard":"public static boolean chunkPayloadComplete(Mp4DashChunk chunk, long declaredBytes) {\n    return chunk.data != null && chunk.data.available() >= declaredBytes;\n}","tryCatchPattern":"try {\n    while ((sample = chunk.nextSample()) != null) { write(sample.data); }\n} catch (EOFException e) {\n    // last sample truncated — keep already-extracted samples, stop gracefully\n    Log.w(TAG, \"chunk ended early: \" + e.getMessage());\n}","preventionTips":["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."],"tags":["mp4","dash","io","truncated-data","samples","java"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}