apache/kafka · error · InvalidReceiveException

Invalid receive (size = ${receiveSize} larger than ${maxSize

Error message

Invalid receive (size = ${receiveSize} larger than ${maxSize})

What it means

Thrown by NetworkReceive.readFrom as an InvalidReceiveException when maxSize is not UNLIMITED and the decoded frame size exceeds maxSize. Kafka caps inbound messages via the channel's maxReceiveSize (broker: message.max.bytes / socket.request.max.bytes; client: socket.request.max.bytes for responses) to protect the broker from oversized or hostile payloads. The check fires after the 4-byte size prefix is read but before the body is allocated, so the channel is torn down before memory is wasted.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/network/NetworkReceive.java:95

    @Override
    public boolean complete() {
        return !size.hasRemaining() && buffer != null && !buffer.hasRemaining();
    }

    public long readFrom(ScatteringByteChannel channel) throws IOException {
        int read = 0;
        if (size.hasRemaining()) {
            int bytesRead = channel.read(size);
            if (bytesRead < 0)
                throw new EOFException();
            read += bytesRead;
            if (!size.hasRemaining()) {
                size.rewind();
                int receiveSize = size.getInt();
                if (receiveSize < 0)
                    throw new InvalidReceiveException("Invalid receive (size = " + receiveSize + ")");
                if (maxSize != UNLIMITED && receiveSize > maxSize)
                    throw new InvalidReceiveException("Invalid receive (size = " + receiveSize + " larger than " + maxSize + ")");
                requestedBufferSize = receiveSize; // may be 0 for some payloads (SASL)
                if (receiveSize == 0) {
                    buffer = EMPTY_BUFFER;
                }
            }
        }
        if (buffer == null && requestedBufferSize != -1) { // we know the size we want but haven't been able to allocate it yet
            buffer = memoryPool.tryAllocate(requestedBufferSize);
            if (buffer == null)
                log.trace("Broker low on memory - could not allocate buffer of size {} for source {}", requestedBufferSize, source);
        }
        if (buffer != null) {
            int bytesRead = channel.read(buffer);
            if (bytesRead < 0)
                throw new EOFException();
            read += bytesRead;
        }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Compare producer max.request.size against the broker's message.max.bytes (and topic-level max.message.bytes) and align them so the producer cap is <= broker cap.
  2. If the oversized payload is legitimate, raise message.max.bytes on the broker, the topic config, and fetch.max.bytes on consumers/replicas accordingly.
  3. Reduce the record size (split records, raise compression, lower batch.size) if the payload should not be that large.

Example fix

# before
producer: max.request.size=20971520
broker:   message.max.bytes=1048588

# after (align caps)
producer: max.request.size=10485760
broker:   message.max.bytes=10485760
Defensive patterns

Strategy: validation

Validate before calling

// Size maxReceiveSize so legitimate responses always fit.
// Producer/consumer: message.max.bytes, fetch.max.bytes, max.partition.fetch.bytes
// Broker: message.max.bytes
long maxExpected = Math.max(messageMaxBytes, fetchMaxBytes);
if (maxExpected > Integer.MAX_VALUE) {
    throw new IllegalArgumentException("max receive size overflows int");
}
Selector selector = new Selector((int) maxExpected, /* ... */);

Try / catch

try {
    long read = networkReceive.readFrom(channel);
} catch (InvalidReceiveException e) {
    log.warn("Receive from {} exceeded maxReceiveSize; closing channel", networkReceive.source(), e);
    Utils.closeQuietly(channel, "channel");
    disconnect(networkReceive.source());
}

Prevention

When it happens

Trigger: A producer publishing a record batch larger than the broker's message.max.bytes, or a client whose request/response exceeds its socket.request.max.bytes; also a malformed frame claiming a huge body. maxSize comes from the Selector constructor's maxReceiveSize parameter.

Common situations: Producer sends a large message/record-batch with max.request.size left high while the broker's message.max.bytes is lower; replication of an oversized message to a follower whose fetch.max.bytes is too small; compression producing a batch that crosses the limit.

Related errors


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