{"record":{"id":"a9aa6c27260f9708","repo":"apache/cassandra","slug":"eof-after-read-bytes-out-of-len","errorCode":null,"errorMessage":"EOF after \" + read + \" bytes out of \" + len","messagePattern":"EOF after \" \\+ read \\+ \" bytes out of \" \\+ len","errorType":"exception","errorClass":"EOFException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/RebufferingInputStream.java","lineNumber":71,"sourceCode":"    /**\n     * Implementations must implement this method to refill the buffer.\n     * They can expect the buffer to be empty when this method is invoked.\n     * @throws IOException\n     */\n    protected abstract void reBuffer() throws IOException;\n\n    @Override\n    public void readFully(byte[] b) throws IOException\n    {\n        readFully(b, 0, b.length);\n    }\n\n    @Override\n    public void readFully(byte[] b, int off, int len) throws IOException\n    {\n        int read = read(b, off, len);\n        if (read < len)\n            throw new EOFException(\"EOF after \" + read + \" bytes out of \" + len);\n    }\n\n    @Override\n    public int read(byte[] b, int off, int len) throws IOException\n    {\n        // avoid int overflow\n        if (off < 0 || off > b.length || len < 0 || len > b.length - off)\n            throw new IndexOutOfBoundsException();\n\n        if (len == 0)\n            return 0;\n\n        int copied = 0;\n        while (copied < len)\n        {\n            int position = buffer.position();\n            int remaining = buffer.limit() - position;\n            if (remaining == 0)","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/RebufferingInputStream.java#L53-L89","documentation":"RebufferingInputStream.readFully(byte[], off, len) implements DataInput's contract: it must fill len bytes or fail. It reads once, and if fewer than len bytes are available it throws EOFException reporting how many bytes were actually read before EOF. This signals the underlying stream ended prematurely.","triggerScenarios":"Calling readFully(b, off, len) (via the single-arg readFully or readLong/readInt wrappers) when the stream holds fewer than len remaining bytes — e.g. a truncated commit-log segment, an sstable cut short, or a deserializer reading past the end of a serialized block.","commonSituations":"Replaying a truncated or partially-flushed commit log on startup; reading corrupted sstable data files; network streams (some wrappers) that ended mid-message; deserializing records from a file written by a newer/older version with different sizes.","solutions":["Check available bytes / file length before readFully and handle short records gracefully","Validate the source file (e.g. sstableverify, commit log segment size vs. actual bytes) — truncation usually means corruption or an unclean shutdown","Wrap in try-catch for EOFException and skip/stop processing the truncated tail instead of crashing","Confirm the writer fully synced/closed the file before the reader consumes it"],"exampleFix":"// before\nin.readFully(header, 0, HEADER_SIZE); // EOFException on truncated file\n// after\nif (in.available() < HEADER_SIZE) {\n    logger.warn(\"Truncated record at end of segment, stopping\");\n    return;\n}\nin.readFully(header, 0, HEADER_SIZE);","handlingStrategy":"try-catch","validationCode":"if (stream.available() < needed) { handleTruncatedTail(); return; } stream.readFully(buf, 0, needed);","typeGuard":"boolean hasEnough = stream != null && stream.available() >= needed;","tryCatchPattern":"try { in.readFully(buf, off, len); } catch (EOFException e) { logger.warn(\"Truncated stream: \" + e.getMessage()); /* stop or skip record */ }","preventionTips":["Check remaining bytes before readFully","Treat EOF as a normal end-of-segment condition in replay code","Verify files after unclean shutdown"],"tags":["io","eof","deserialization"],"backgroundTag":"unexpected-eof","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}