apache/cassandra · error · EOFException
EOF after " + copied + " bytes out of " + len
Error message
EOF after " + copied + " bytes out of " + len
What it means
The bulk variant RebufferingInputStream.readFully(DataOutputBuffer dst/byte[], off, len) copies bytes across rebuffer() cycles until it has all len bytes; when a rebuffer yields zero remaining bytes before the request is satisfied it throws EOFException('EOF after <copied> bytes out of <len>'). It means the stream ended mid-read, i.e. truncated data.
Source
Thrown at src/java/org/apache/cassandra/io/util/RebufferingInputStream.java:128
{
int offset = dst.position();
int len = dst.limit() - offset;
int copied = 0;
while (copied < len)
{
int position = buffer.position();
int remaining = buffer.limit() - position;
if (remaining == 0)
{
reBuffer();
position = buffer.position();
remaining = buffer.limit() - position;
if (remaining == 0)
throw new EOFException("EOF after " + copied + " bytes out of " + len);
}
int toCopy = min(len - copied, remaining);
FastByteOperations.copy(buffer, position, dst, offset + copied, toCopy);
buffer.position(position + toCopy);
copied += toCopy;
}
}
@DontInline
protected long readPrimitiveSlowly(int bytes) throws IOException
{
long result = 0;
for (int i = 0; i < bytes; i++)
result = (result << 8) | (readByte() & 0xFFL);
return result;
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Sanity-check the declared length against remaining file bytes before the bulk readFully
- Try-catch EOFException and treat the record as corrupt/truncated — stop or resync per protocol
- Verify the data file (sstableverify/scrub, commit log replay truncation handling) to locate the corruption
- Ensure readers only see fully-synced files and match serialization versions between reader and writer
Example fix
// before
dob = new DataOutputBuffer();
in.readFully(dob, (int) declaredSize); // EOF mid-copy on corrupt length
// after
long readable = fileLength - in.getPosition();
if (declaredSize > readable) {
throw new CorruptFileException("declared size " + declaredSize + " exceeds remaining " + readable);
}
in.readFully(dob, (int) declaredSize); Defensive patterns
Strategy: try-catch
Validate before calling
long readable = fileLength - currentPosition; if (declaredSize > readable) { throw new CorruptFileException("size " + declaredSize + " > remaining " + readable); } Type guard
boolean fits = declaredSize >= 0 && declaredSize <= (fileLength - currentPosition);
Try / catch
try { in.readFully(dob, len); } catch (EOFException e) { logger.warn("Truncated record: " + e.getMessage()); /* mark corrupt, resync */ } Prevention
- Validate length prefixes against file size before bulk reads
- Catch EOFException at record boundaries and resynchronize
- Run sstableverify/scrub on suspicious files
- Keep serialization versions in sync between writer and reader
When it happens
Trigger: Reading a record larger than what physically remains in the stream — reading past the last entry of a commit-log segment, deserializing a partition whose declared size exceeds the file, or copying a blob whose length field is corrupt so the copy loop hits EOF partway.
Common situations: Corrupted length prefixes in sstable/commit-log data causing oversized reads; truncated files from unclean shutdown or failed disk; reading a file still being written; version mismatch making the reader expect more bytes than the writer produced.
Related errors
- EOF after " + read + " 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/3c0ed0eb4dc91525.
Report an issue: GitHub.