apache/kafka · critical · InvalidRecordException
Found invalid wrapper offset in compressed v1 message set, w
Error message
Found invalid wrapper offset in compressed v1 message set, wrapper offset '{}' is less than the last inner message offset '{}' and it is not zero. What it means
Thrown by DeepRecordsIterator (line 381) as an InvalidRecordException for magic v1 compressed message sets when the wrapper's lastOffset is non-zero but smaller than the last inner record's offset. v1 uses relative offsets: wrapper.lastOffset must equal absolute last offset, and the inner last offset is a relative value, so wrapper offset < inner last offset is impossible for well-formed data unless the wrapper offset was rewritten incorrectly.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/AbstractLegacyRecordBatch.java:381
timestampFromWrapper,
wrapperRecord.timestampType());
innerEntry = new BasicLegacyRecordBatch(innerEntry.lastOffset(), recordWithTimestamp);
}
innerEntries.addLast(innerEntry);
}
if (innerEntries.isEmpty())
throw new InvalidRecordException("Found invalid compressed record set with no inner records");
if (wrapperMagic == RecordBatch.MAGIC_VALUE_V1) {
if (lastOffsetFromWrapper == 0) {
// The outer offset may be 0 if this is produce data from certain versions of librdkafka.
this.absoluteBaseOffset = 0;
} else {
long lastInnerOffset = innerEntries.getLast().offset();
if (lastOffsetFromWrapper < lastInnerOffset)
throw new InvalidRecordException("Found invalid wrapper offset in compressed v1 message set, " +
"wrapper offset '" + lastOffsetFromWrapper + "' is less than the last inner message " +
"offset '" + lastInnerOffset + "' and it is not zero.");
this.absoluteBaseOffset = lastOffsetFromWrapper - lastInnerOffset;
}
} else {
this.absoluteBaseOffset = -1;
}
} catch (IOException e) {
throw new KafkaException(e);
} finally {
Utils.closeQuietly(stream, "records iterator stream");
}
}
@Override
protected Record makeNext() {
if (innerEntries.isEmpty())
return allDone();View on GitHub (pinned to c31c9215e1)
Solutions
- Do not rewrite offsets on compressed v1 batches in custom tooling; let the broker assign offsets at produce time.
- Migrate the topic to message.format.version 0.11+ (v2), which uses a base offset + count scheme that is far less prone to this class of bug.
- If the bad data is historical, identify the segment with kafka-dump-log --deep-iteration, drop the corrupt range, and restore from a clean replica or backup.
- Upgrade any offset-rewriting component (MirrorMaker, replication tools) to a version that correctly handles v1 compressed batches or that converts to v2.
Defensive patterns
Strategy: try-catch
Try / catch
// For v1 compressed batches the wrapper offset must be >= the last inner offset
// (or exactly 0). A violation means offsets are corrupt.
import org.apache.kafka.common.errors.InvalidRecordException;
try {
for (Record r : legacyBatch) { /* process */ }
} catch (InvalidRecordException e) {
log.error("Legacy v1 compressed batch has inconsistent wrapper/inner offsets; skipping", e);
} Prevention
- Offsets are assigned by the broker; never rewrite wrapper or inner offsets client-side on compressed legacy batches.
- Avoid using non-Apache-Kafka producers that fabricate offsets for compressed v1 batches; the librdkafka offset-0 special case is the only tolerated exception.
- When migrating offsets or repairing log segments, recompute the wrapper offset as last-inner-offset + (count-1) plus the absolute base, or use the broker's offset-assignment path.
- Treat the batch as corrupt; skip and alert rather than retry.
When it happens
Trigger: A compressed v1 batch whose wrapper offset was reassigned (e.g. by a buggy broker assignor or replication path) to a value smaller than the relative offset of its last inner record, without being reset to zero. Also triggered by tooling that rewrites offsets (kafka-reassign-partitions, mirror-maker, custom offset translators) incorrectly.
Common situations: MirrorMaker or other offset-rewriting pipelines that lower the wrapper offset without recomputing inner offsets. A broker bug in offset assignment during log compaction or replication of v1 compressed batches. Custom tooling that edits the offset field of a compressed v1 batch in place.
Related errors
- Compressed message magic {} does not match wrapper magic {}
- Found invalid compressed record set with no inner records
- Inner messages must not be compressed
- Invalid negative offset
- Invalid negative offset
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/9b46f0949c7e206d.json.
Report an issue: GitHub.