apache/kafka · error · InvalidRecordException
Found invalid number of record headers. {} is larger than th
Error message
Found invalid number of record headers. {} is larger than the remaining size of the buffer What it means
Thrown on the ByteBuffer path when numHeaders is non-negative but greater than buffer.remaining(). Since each header needs at least one byte, the count cannot fit in the remaining payload; the library treats this as structural corruption rather than trying to read past the buffer limit.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/DefaultRecord.java:342
int offsetDelta = ByteUtils.readVarint(buffer);
long offset = baseOffset + offsetDelta;
int sequence = baseSequence >= 0 ?
DefaultRecordBatch.incrementSequence(baseSequence, offsetDelta) :
RecordBatch.NO_SEQUENCE;
// read key
int keySize = ByteUtils.readVarint(buffer);
ByteBuffer key = Utils.readBytes(buffer, keySize);
// 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);
}
}View on GitHub (pinned to c31c9215e1)
Solutions
- Confirm the producer is on a supported client version and uses the standard record builder; capture a single failing record with kafka-console-consumer --max-messages 1 and hex-inspect the header section.
- Check the broker log for CRC validation failures on the same partition/offset to distinguish in-flight corruption from on-disk corruption.
- If only one partition is affected, stop the affected producer, validate its header construction, and re-publish the bad batch.
- Recover the segment from an in-sync replica if disk corruption is confirmed by kafka-dump-log.
Defensive patterns
Strategy: validation
Validate before calling
// After you decode numHeaders, before letting the parser continue:
if (numHeaders > buffer.remaining()) {
// declared header count cannot fit; record is corrupt or truncated
throw new InvalidRecordException("declared headers exceed remaining buffer");
} Type guard
// Bounds-check the header count against the remaining payload.
private static boolean headersFitInBuffer(int numHeaders, ByteBuffer buffer) {
return numHeaders >= 0 && numHeaders <= buffer.remaining();
} Try / catch
try {
DefaultRecord r = DefaultRecord.readFrom(buffer, baseOffset, baseTimestamp, baseSequence, logAppendTime);
} catch (InvalidRecordException e) {
LOG.warn("Header count exceeds remaining bytes near offset {}", baseOffset, e);
} Prevention
- Remember numHeaders is an upper bound only if each header is >=1 byte; always also trust the parser's later per-header size checks.
- When authoring records, cap header count and total header bytes well below the record size limit.
- Catch InvalidRecordException at the batch iterator level so one bad record does not abort the whole poll.
When it happens
Trigger: Raised at DefaultRecord.java:341-342 when ByteUtils.readVarint returns a header count larger than buffer.remaining() after the key/value sections have already been consumed. Common when the headers count field was overwritten with a large value or when the key/value length prefixes were misread, leaving too few bytes for the claimed header array.
Common situations: Producer client producing records where key/value lengths disagree with the actual bytes (off-by-one in a custom partitioner/serializer), corruption of the batch in the page cache or on disk, or a consumer pointed at a topic that another vendor's broker wrote in a subtly different record format.
Related errors
- Found invalid number of record headers {}
- Invalid negative header key size {}
- Invalid record size: expected {} bytes in record payload, bu
- Invalid record size: expected to read {} bytes in record pay
- Found invalid record structure
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/9240a84adafb8dc8.json.
Report an issue: GitHub.