apache/kafka · error · InvalidRecordException
Invalid record size: expected to read {} bytes in record pay
Error message
Invalid record size: expected to read {} bytes in record payload, but instead read {} What it means
Thrown after the record is fully parsed when the bytes consumed from recordStart to current position do not equal the declared body size. It is a self-consistency check on the magic-v2 record framing: every field read correctly but the total length disagrees with the size prefix, so the structure is corrupt.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/DefaultRecord.java:352
// read value
int valueSize = ByteUtils.readVarint(buffer);
ByteBuffer value = Utils.readBytes(buffer, valueSize);
int numHeaders = ByteUtils.readVarint(buffer);
if (numHeaders < 0)
throw new InvalidRecordException("Found invalid number of record headers " + numHeaders);
if (numHeaders > buffer.remaining())
throw new InvalidRecordException("Found invalid number of record headers. " + numHeaders + " is larger than the remaining size of the buffer");
final Header[] headers;
if (numHeaders == 0)
headers = Record.EMPTY_HEADERS;
else
headers = readHeaders(buffer, numHeaders);
// validate whether we have read all header bytes in the current record
if (buffer.position() - recordStart != sizeOfBodyInBytes)
throw new InvalidRecordException("Invalid record size: expected to read " + sizeOfBodyInBytes +
" bytes in record payload, but instead read " + (buffer.position() - recordStart));
int totalSizeInBytes = ByteUtils.sizeOfVarint(sizeOfBodyInBytes) + sizeOfBodyInBytes;
return new DefaultRecord(totalSizeInBytes, attributes, offset, timestamp, sequence, key, value, headers);
} catch (BufferUnderflowException | IllegalArgumentException e) {
throw new InvalidRecordException("Found invalid record structure", e);
}
}
public static PartialDefaultRecord readPartiallyFrom(InputStream input,
long baseOffset,
long baseTimestamp,
int baseSequence,
Long logAppendTime) throws IOException {
int sizeOfBodyInBytes = ByteUtils.readVarint(input);
int totalSizeInBytes = ByteUtils.sizeOfVarint(sizeOfBodyInBytes) + sizeOfBodyInBytes;
return readPartiallyFrom(input, totalSizeInBytes, baseOffset, baseTimestamp,View on GitHub (pinned to c31c9215e1)
Solutions
- Identify the producing client for the failing partition/offset and confirm it goes through the Apache Kafka producer path; remove any interceptors that mutate record bytes.
- Round-trip the suspected record through DefaultRecord.writeTo / readFrom in a unit test to find which field's length prefix disagrees with its payload.
- Validate the batch CRC with kafka-dump-log; if CRC fails the data is corrupt on disk or in transit, otherwise the producer itself emitted a malformed frame.
- Recover the affected log segment from a healthy replica or skip the corrupt record with the consumer's isolation/auto-reset policy if data loss is acceptable.
Defensive patterns
Strategy: try-catch
Validate before calling
// You would have to re-walk attributes+timestampDelta+offsetDelta+key+value+ // headers to predict total bytes. Not practical; rely on the parser's own // recordStart/position() check and catch the exception.
Try / catch
try {
DefaultRecord r = DefaultRecord.readFrom(buffer, baseOffset, baseTimestamp, baseSequence, logAppendTime);
} catch (InvalidRecordException e) {
// bytes consumed != sizeOfBodyInBytes declared in the varint length prefix
LOG.warn("Record length mismatch near offset {}", baseOffset, e);
} Prevention
- This signals a length-prefix / payload mismatch; ensure the producer and broker agree on the message-format version (v2 since 0.11).
- Do not splice records across batches; respect the batch length prefix.
- Run integration tests with the same client versions on producer and consumer to avoid format drift.
When it happens
Trigger: Raised at DefaultRecord.java:351-353 inside readFrom(ByteBuffer, ...) when (buffer.position() - recordStart) != sizeOfBodyInBytes after key, value, and headers were all read. Happens when one of the varint length fields (keySize, valueSize, numHeaders, headerKeySize, headerValueSize) was decoded successfully but consumed a number of bytes that does not sum to the declared body length.
Common situations: Custom interceptor or Converter that rewrites a record body without updating the outer size varint, a serialization library that mis-encodes a varint, version skew between a broker using one record-batch framing and a client expecting another, or partial on-disk corruption that left individual fields readable but the total length wrong.
Related errors
- Invalid record size: expected {} bytes in record payload, bu
- Found invalid number of record headers {}
- Found invalid number of record headers. {} is larger than th
- Found invalid record structure
- Invalid negative header key size {}
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/9681b52e0148b34f.json.
Report an issue: GitHub.