{"record":{"id":"2dff472d27d43943","repo":"TeamNewPipe/NewPipe","slug":"truncated-stream-missing-bytes","errorCode":null,"errorMessage":"Truncated stream, missing {} bytes","messagePattern":"Truncated stream, missing (.+?) bytes","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/org/schabi/newpipe/streams/DataReader.java","lineNumber":238,"sourceCode":"                public boolean markSupported() {\n                    return false;\n                }\n\n            };\n        }\n        viewSize = size;\n\n        return view;\n    }\n\n    private final short[] primitive = new short[LONG_SIZE];\n\n    private void primitiveRead(final int amount) throws IOException {\n        final byte[] buffer = new byte[amount];\n        final int read = read(buffer, 0, amount);\n\n        if (read != amount) {\n            throw new EOFException(\"Truncated stream, missing \"\n                    + (amount - read) + \" bytes\");\n        }\n\n        for (int i = 0; i < amount; i++) {\n            // the \"byte\" data type in java is signed and is very annoying\n            primitive[i] = (short) (buffer[i] & 0xFF);\n        }\n    }\n\n    private final byte[] readBuffer = new byte[BUFFER_SIZE];\n    private int readOffset;\n    private int readCount;\n\n    private boolean fillBuffer() throws IOException {\n        if (readCount < 0) {\n            return true;\n        }\n        if (readOffset >= readBuffer.length) {","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/org/schabi/newpipe/streams/DataReader.java#L220-L256","documentation":"DataReader.primitiveRead tries to read a fixed number of bytes (2, 4, or 8) for a primitive Java type (short/int/long) but the underlying SharpStream returned fewer bytes than requested. The EOFException reports how many bytes are missing (amount - read). It fires from the internal primitive-read path used by readShort/readInt/readLong/readFloat, so any truncated or prematurely closed media stream surfaces here.","triggerScenarios":"Calling readShort()/readInt()/readLong()/readFloat() on a DataReader whose underlying SharpStream reaches EOF mid-primitive. This occurs when Mp4DashReader or WebMReader reads a box/element header (size, type, encoded length) and the source ends before the full primitive is delivered.","commonSituations":"An incomplete download whose byte count is short; a network stream interrupted mid-transfer; a cached file truncated by disk-full or a previous failed write; a server serving a Content-Length larger than the actual body. Most often seen on flaky mobile connections where the demuxer starts before the full payload arrives.","solutions":["Verify the source stream length before parsing; reject inputs whose reported size is smaller than a minimum valid header (e.g. compare against expected atom/element sizes).","Re-fetch or re-download the media file — a truncated stream is almost always a corrupted/incomplete download.","If reading from a pipe/network socket, ensure the producer fully flushes and closes before the consumer begins primitive reads.","Catch EOFException at the parse entry point and report a user-facing 'file is incomplete' message rather than crashing."],"exampleFix":"// before\nDataReader dr = new DataReader(source);\nlong size = dr.readLong(); // throws if source truncated mid-8-bytes\n\n// after — guard with available()/length first\nif (!source.isLengthKnown() || source.length() < LONG_SIZE) {\n    throw new IOException(\"source too short to be a valid container\");\n}\nlong size = dr.readLong();","handlingStrategy":"validation","validationCode":"// Before constructing DataReader, confirm the source has enough bytes for the operation.\nif (!source.isLengthKnown() || source.length() < minHeaderBytes) {\n    throw new IOException(\"source too short to parse a valid container\");\n}\nDataReader dr = new DataReader(source);","typeGuard":"// Java has no opaque 'maybe-truncated' type; encode the contract in a wrapper.\npublic final class LengthVerifiedStream extends SharpStream {\n    private final SharpStream inner;\n    private final long minLen;\n    public LengthVerifiedStream(SharpStream inner, long minLen) {\n        if (inner.isLengthKnown() && inner.length() < minLen)\n            throw new IllegalArgumentException(\"source shorter than \" + minLen);\n        this.inner = inner; this.minLen = minLen;\n    }\n    // delegate read()/skip() ...\n}","tryCatchPattern":"try {\n    long v = dr.readLong();\n} catch (EOFException e) {\n    // truncated primitive read — source is incomplete, do not retry the same stream\n    throw new IOException(\"media stream truncated: \" + e.getMessage(), e);\n}","preventionTips":["Always verify the download completed (full Content-Length) before demuxing.","Prefer length-known streams (RandomAccessFile/local file) over open-ended network sockets for parsing.","Validate a minimum header size before the first primitive read.","Do not resume parsing on a partially-written cache file."],"tags":["io","stream","truncated-data","mp4","webm","java"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}