apache/cassandra · error · EOFException
EOF after <skipped> bytes out of <n>
Error message
EOF after <skipped> bytes out of <n>
What it means
DataInputPlus.skipBytesFully(n) is a strict skip: it calls skipBytes(n) and throws EOFException if fewer bytes could be skipped than requested, guaranteeing callers that the stream is positioned exactly n bytes past the start and that the underlying source still had the data.
Source
Thrown at src/java/org/apache/cassandra/io/util/DataInputPlus.java:126
| (readByte() & 0xffL);
case 8: return readLong();
default: throw new IllegalArgumentException();
}
}
/**
* Always skips the requested number of bytes, unless EOF is reached
*
* @param n number of bytes to skip
* @return number of bytes skipped
*/
public int skipBytes(int n) throws IOException;
public default void skipBytesFully(int n) throws IOException
{
int skipped = skipBytes(n);
if (skipped != n)
throw new EOFException("EOF after " + skipped + " bytes out of " + n);
}
@Override
default byte readByte() throws IOException
{
return (byte) readUnsignedByte();
}
@Override
default boolean readBoolean() throws IOException
{
return readUnsignedByte() != 0;
}
@Override
default short readShort() throws IOException
{
int ch1 = readUnsignedByte();View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Treat the file/segment as truncated: stop reading at the last known-good offset (e.g. use CommitLogDescriptor/segment checksums to find the safe end).
- Restore or repair the data file from replica/backup if the corrupted source must be recovered.
- Verify reader and writer use the same serialization format/version; a mismatched schema can make lengths bogus.
- Catch EOFException in the streaming path and skip the damaged record rather than failing the whole operation.
Example fix
// before
in.skipBytesFully(rowBodySize);
// after
try {
in.skipBytesFully(rowBodySize);
} catch (EOFException e) {
logger.warn("Truncated record, aborting read at {}", in);
throw e; // or stop processing this segment
}
Defensive patterns
Strategy: try-catch
Validate before calling
// check declared length against remaining bytes when the input exposes it // e.g. if (declaredLength > input.availableBytes()) throw before skipping
Try / catch
try { input.skipBytesFully(n); }
catch (EOFException e) { abortSegment(e); /* stop at last good offset */ } Prevention
- Validate length fields against file size before skipping
- Use checksummed inputs (ChecksummedDataInput) to detect truncation early
- Don't read files still being written
- Handle partial commit-log/SSTable segments as normal crash recovery
When it happens
Trigger: Skipping a row body / cell value / serialized field whose declared length exceeds the remaining bytes in the stream — typically reading a truncated or corrupted SSTable row, commit log segment, or handoff file; or a length field read incorrectly due to format mismatch.
Common situations: Streaming/compacting a truncated SSTable; replaying a partially flushed commit log; reading inter-node message or hinted-handoff data cut short by a crash; deserializing with a serializer whose layout doesn't match the written one.
Related errors
- Corrupted sstable. Invalid flags found deserializing Deletio
- Expected exactly %d bytes, but was %d
- Impossible partition size (greater than file length):
- Incomplete file: header stipulated <length> bytes but found
- EOF after " + read + " bytes out of " + len
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/6d6bca827e393745.
Report an issue: GitHub.