apache/kafka · error · IllegalArgumentException

Invalid size: {} in read from {}

Error message

Invalid size: {} in read from {}

What it means

Thrown by FileRecords.availableBytes when the requested size argument is negative. A negative read length is undefined for FileChannel transfers, so the guard rejects it before computing the end offset. Like the position check, this is a programmer-error guard against malformed slice/sliceUnaligned calls.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/FileRecords.java:177

     * @return A unaligned slice of records on this message set limited based on the given position and size
     */
    public UnalignedFileRecords sliceUnaligned(int position, int size) {
        int availableBytes = availableBytes(position, size);
        return new UnalignedFileRecords(channel, this.start + position, availableBytes);
    }

    private int availableBytes(int position, int size) {
        // Cache current size in case concurrent write changes it
        int currentSizeInBytes = sizeInBytes();

        if (position < 0)
            throw new IllegalArgumentException("Invalid position: " + position + " in read from " + this);
        // position should always be relative to the start of the file hence compare with file size
        // to verify if the position is within the file.
        if (position > currentSizeInBytes)
            throw new IllegalArgumentException("Slice from position " + position + " exceeds end position of " + this);
        if (size < 0)
            throw new IllegalArgumentException("Invalid size: " + size + " in read from " + this);

        int end = this.start + position + size;
        // Handle integer overflow or if end is beyond the end of the file
        if (end < 0 || end > start + currentSizeInBytes)
            end = this.start + currentSizeInBytes;
        return end - (this.start + position);
    }

    /**
     * Append a set of records to the file. This method is not thread-safe and must be
     * protected with a lock.
     *
     * @param records The records to append
     * @return the number of bytes written to the underlying file
     */
    public int append(MemoryRecords records) throws IOException {
        if (records.sizeInBytes() > Integer.MAX_VALUE - size.get())
            throw new IllegalArgumentException("Append of size " + records.sizeInBytes() +

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Trace the caller of slice/sliceUnaligned and confirm the size argument is derived from a non-negative length, not a signed difference.
  2. Bound the size at the source: use Math.max(0, end - start) before passing it in.
  3. Check fetch-size config (max.partition.fetch.bytes, fetch.max.bytes) for negative or absurd values.

Example fix

// before: size can go negative when end < start
int size = endOffset - startOffset;
return records.slice(position, size);

// after: clamp size so negative deltas become zero-length reads
int size = Math.max(0, endOffset - startOffset);
return records.slice(position, size);
Defensive patterns

Strategy: validation

Validate before calling

if (size < 0) {
    throw new IllegalArgumentException(
        "read/slice size must be >= 0, got " + size);
}
FileRecords slice = records.slice(position, size);

Prevention

When it happens

Trigger: Calling FileRecords.slice(position, size) or sliceUnaligned(position, size) with a negative size. Reachable from fetch/replication code paths that compute the read length from an offset difference or from min(fetchSize, ...) expressions.

Common situations: Subtracting a larger number from a smaller one (e.g. endOffset - startOffset when the start is past the end), an off-by-one in fetch min/max math, or a misconfigured fetch.min.bytes/fetch.max.bytes. Rare in production code paths; more common in tests and custom consumers.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/cdfefff7d9c6c0dc.json. Report an issue: GitHub.