Kafka CRC32C Calculator

Compute CRC32C and CRC32 over any bytes, or paste a whole record batch and have its stored checksum checked. When it does not match, the report names which mistake produced the number you have.

Hex is tried before base64, because a hex string is often valid as both and nobody pasting 0a1b2c3d means base64. Separators, newlines and 0x prefixes are stripped. The bytes decide the checksum, so reading four text characters rather than two bytes is a different and equally valid answer to a different question.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Checksum. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

CRC32C against CRC32

Kafka uses CRC32C (Castagnoli) since 0.11, and the two differ for the same bytes

hello world

A longer payload

The same two checksums over a realistic record value

{"orderId":1001,"status":"shipped","total":42.5}

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Using CRC32 where Kafka uses CRC32C

    Kafka moved to CRC32C (Castagnoli) with the v2 record batch format in 0.11. The polynomials differ, so the checksums differ for the same bytes.

    Instead:Use CRC32C for anything touching modern Kafka batches.

  2. Computing the CRC over the whole batch

    The batch CRC covers the bytes AFTER the CRC field, not the whole batch. Including the header bytes gives a value that will never match.

    Instead:Start from the attributes field, which is where the broker starts.

Why a Kafka checksum disagrees

Four causes, and only one of them is actually damaged data. The other three are all mistakes in how the number was computed.

There are two algorithms, and they changed at the same time as the format

Message formats v0 and v1 use CRC32, the zlib polynomial that `gzip`, `png` and almost every command line `crc32` tool computes. Format v2, from Kafka 0.11 onward, uses CRC32C, the Castagnoli polynomial. A library that hardcodes one of them produces a checksum the broker rejects, and the failure reads as corruption. This page computes both every time, so a value that matches the other one identifies the bug immediately.

The v2 checksum does not cover the whole batch

It covers from the attributes field at offset 21 to the end. In front of it sit the base offset, the batch length and the partition leader epoch, and then the checksum field itself. The reason is that the broker rewrites some of those: the partition leader epoch changes on a leader election and the base offset is assigned on append, so a checksum covering them would be invalidated by the broker's own normal behaviour. Anything that covers them was computed over the wrong range.

A truncated paste is the most likely cause of all

A v2 batch declares its own length in the four bytes at offset 8, counting everything after that field. If the buffer is shorter than the batch says it should be, nothing is wrong with the bytes that are there and there is simply less of them, which explains the mismatch on its own. If it is longer, that is usually several batches concatenated and each has to be checked separately. This page reports the difference rather than leaving it to be guessed at.

A checksum is not a signature

CRC32C detects accidental change: a flipped bit on a wire, a bad disk sector, a truncated write. It detects nothing deliberate, because anyone who alters the bytes can recompute it in a microsecond. A matching checksum means the batch survived transport, and says nothing at all about where it came from. If you need that, you need authentication, not a checksum.

What this cannot see

It reads bytes and checks arithmetic. It does not parse the records inside a batch, decode their keys or values, or validate anything about the compression codec named in the attributes field, which means a batch whose payload is compressed is checksummed as the compressed bytes it is, exactly as the broker does. For decoding a payload, the Confluent wire format decoder on this site reads the five bytes in front of a Schema Registry message.