apache/cassandra · error · EOFException

EOF after " + read + " bytes out of " + len

Error message

EOF after " + read + " bytes out of " + len

What it means

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.

Source

Thrown at src/java/org/apache/cassandra/io/util/RebufferingInputStream.java:71

    /**
     * Implementations must implement this method to refill the buffer.
     * They can expect the buffer to be empty when this method is invoked.
     * @throws IOException
     */
    protected abstract void reBuffer() throws IOException;

    @Override
    public void readFully(byte[] b) throws IOException
    {
        readFully(b, 0, b.length);
    }

    @Override
    public void readFully(byte[] b, int off, int len) throws IOException
    {
        int read = read(b, off, len);
        if (read < len)
            throw new EOFException("EOF after " + read + " bytes out of " + len);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException
    {
        // avoid int overflow
        if (off < 0 || off > b.length || len < 0 || len > b.length - off)
            throw new IndexOutOfBoundsException();

        if (len == 0)
            return 0;

        int copied = 0;
        while (copied < len)
        {
            int position = buffer.position();
            int remaining = buffer.limit() - position;
            if (remaining == 0)

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Check available bytes / file length before readFully and handle short records gracefully
  2. Validate the source file (e.g. sstableverify, commit log segment size vs. actual bytes) — truncation usually means corruption or an unclean shutdown
  3. Wrap in try-catch for EOFException and skip/stop processing the truncated tail instead of crashing
  4. Confirm the writer fully synced/closed the file before the reader consumes it

Example fix

// before
in.readFully(header, 0, HEADER_SIZE); // EOFException on truncated file
// after
if (in.available() < HEADER_SIZE) {
    logger.warn("Truncated record at end of segment, stopping");
    return;
}
in.readFully(header, 0, HEADER_SIZE);
Defensive patterns

Strategy: try-catch

Validate before calling

if (stream.available() < needed) { handleTruncatedTail(); return; } stream.readFully(buf, 0, needed);

Type guard

boolean hasEnough = stream != null && stream.available() >= needed;

Try / catch

try { in.readFully(buf, off, len); } catch (EOFException e) { logger.warn("Truncated stream: " + e.getMessage()); /* stop or skip record */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/a9aa6c27260f9708. Report an issue: GitHub.