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

  1. Sanity-check the declared length against remaining file bytes before the bulk readFully
  2. Try-catch EOFException and treat the record as corrupt/truncated — stop or resync per protocol
  3. Verify the data file (sstableverify/scrub, commit log replay truncation handling) to locate the corruption
  4. 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

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


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