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
- 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.
- If the oversized payload is legitimate, raise message.max.bytes on the broker, the topic config, and fetch.max.bytes on consumers/replicas accordingly.
- 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
- Set client fetch.max.bytes / max.partition.fetch.bytes and broker message.max.bytes consistently so the largest legitimate message fits under maxReceiveSize.
- Use compression to keep produced messages under message.max.bytes.
- Remember maxReceiveSize defends the broker/client; raising it too high exposes you to memory-exhaustion DoS.
- Treat oversized-receive as connection-fatal: close and reconnect rather than retrying inline.
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
- Invalid receive (size = ${receiveSize})
- Unknown host in bootstrap.servers: {url}
- Record size exceeds the largest allowable message size (%d).
- Invalid url in bootstrap.servers: {url}
- Invalid url in bootstrap.servers: {url}
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/443353b3ab81e0e4.json.
Report an issue: GitHub.