apache/kafka · error · CorruptRecordException
Record is corrupt (stored crc = {}, computed crc = {})
Error message
Record is corrupt (stored crc = {}, computed crc = {}) What it means
Thrown by LegacyRecord.ensureValid when the record is large enough to hold a CRC but the stored CRC does not match the value recomputed from the record body. This is the canonical on-disk corruption signal for message-format v0/v1 records; the message text prints both CRC values to aid diagnosis. It is a CorruptRecordException.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/LegacyRecord.java:136
}
/**
* Returns true if the crc stored with the record matches the crc computed off the record contents
*/
public boolean isValid() {
return sizeInBytes() >= RECORD_OVERHEAD_V0 && checksum() == computeChecksum();
}
/**
* Throw an CorruptRecordException if isValid is false for this record
*/
public void ensureValid() {
if (sizeInBytes() < RECORD_OVERHEAD_V0)
throw new CorruptRecordException("Record is corrupt (crc could not be retrieved as the record is too "
+ "small, size = " + sizeInBytes() + ")");
if (!isValid())
throw new CorruptRecordException("Record is corrupt (stored crc = " + checksum()
+ ", computed crc = " + computeChecksum() + ")");
}
/**
* The complete serialized size of this record in bytes (including crc, header attributes, etc), but
* excluding the log overhead (offset and record size).
* @return the size in bytes
*/
public int sizeInBytes() {
return buffer.limit();
}
/**
* The length of the key in bytes
* @return the size in bytes of the key (0 if the key is null)
*/
public int keySize() {
if (magic() == RecordBatch.MAGIC_VALUE_V0)View on GitHub (pinned to c31c9215e1)
Solutions
- Run log recovery with the recovery-point checkpoint deleted so the broker truncates back to the last validated offset.
- Restore the affected partition from a healthy in-sync replica; do not attempt to patch CRCs by hand.
- Run filesystem-level checks (fsck/xfs_repair) and smartctl on the underlying device to find the source of corruption.
- Move to message.format.version 2 (or higher) where batches have both CRC and length checks, and enable log.message.format.version interop carefully during upgrade.
Example fix
// before: every consumed legacy record must pass strict CRC validation
for (LegacyRecord r : legacyRecords) r.ensureValid();
// after: tolerate known-corrupt tail records during recovery, fail loud on the rest
for (LegacyRecord r : legacyRecords) {
try { r.ensureValid(); }
catch (CorruptRecordException e) {
if (recovery) log.warn("Skipping corrupt record at offset {} during recovery", offset);
else throw e;
}
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!record.isValid()) {
log.warn("CRC mismatch on record: stored {}, computed {}; skipping",
record.checksum(), record.computeChecksum());
continue;
} Try / catch
try {
record.ensureValid();
} catch (CorruptRecordException e) {
// disk or network bit-rot; quarantine the batch and advance past it
log.warn("Corrupt record (CRC mismatch)", e);
consumer.seekToEnd(); // or quarantine segment for repair
} Prevention
- Call record.isValid() before trusting record contents rather than relying solely on ensureValid().
- Investigate recurring CRC failures: failing disk, bad NIC/cable, or a misbehaving producer.
- Keep CRC validation enabled in the consumer; never disable it for throughput.
- Replicate corrupt segments off the hot path for forensic comparison.
When it happens
Trigger: Invoking LegacyRecord.ensureValid() (or isValid()) on a v0/v1 record whose bytes were altered after the CRC was written. Reached during log recovery, fetch validation, and produce-side validation of legacy-format batches.
Common situations: Disk bit-rot or controller/firmware bugs, silent data corruption from a faulty NIC or RAM, partial writes from unclean shutdown, or a producer that hand-rolled records without recomputing the CRC. Also seen after restoring from a backup that did not fsync.
Related errors
- Record is corrupt (crc could not be retrieved as the record
- Record batch for partition {} at offset {} is invalid, cause
- Record for partition {} at offset {} is invalid, cause: {}
- Encountered corrupt message when fetching offset {} for topi
- Record size is less than the minimum record overhead (%d)
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/7c7ac291b4973b95.json.
Report an issue: GitHub.