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
- 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
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
- Check remaining bytes before readFully
- Treat EOF as a normal end-of-segment condition in replay code
- Verify files after unclean shutdown
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
- EOF after " + copied + " bytes out of " + len
- Corrupt flags value for clustering prefix (isStatic flag set
- Corrupt (negative) value length encountered
- Corrupt value length %d encountered, as it exceeds the maxim
- Invalid large Columns subset: present index ${idx} of ${supe
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a9aa6c27260f9708.
Report an issue: GitHub.