Description
When consuming from a cluster or topic that stores messages in the legacy MessageSet format (log.message.format.version < 0.11, MsgVersion v0..v1), every message is delivered to the application with NULL key and NULL value: fetches succeed and offsets advance, but all payloads are NULL. Offsets and timestamps are correct. The consumer also raises errors such as:
Unsupported Message(Set) MagicByte 97 at offset 1525458452426752
Bisected to 6867b9f ("Fetch RPC prework: upgrade to v15", #4584, v2.5.0): since Fetch v12+ the response buffer is parsed as a flexible version, and the legacy MessageSet reader reads Message Key/Value with rd_kafka_buf_read_kbytes(), which switches to compact (varint) length parsing for flexible-version buffers. Legacy MessageSets always use fixed-width int32 length prefixes, so the first 0x00 length byte parses as a compact NULL and the reader drifts into the message bytes (the MagicByte 97 above is a payload byte). On v2.5.x fetches fail/stall instead; from v2.6.0 onwards messages are delivered with NULL key/value as described. Still present on v2.15.0/master.
Found in production through node-rdkafka 3.6.1 (librdkafka 2.12.0), consuming from Apache Kafka 3.9.1 brokers that pin log.message.format.version=0.10.2.2 for rolling-upgrade compatibility.
How to reproduce
Run any broker with log.message.format.version=0.10.2.2 (e.g. Apache Kafka 3.9 in ZooKeeper mode with inter.broker.protocol.version=0.10.2.2), produce keyed messages, consume them: all messages arrive with NULL key/value. The fix PR adds a mock-broker regression test (0187) that reproduces this by capping the ProduceRequest version to <= v2 so the producer writes MsgVersion v1/v0 MessageSets.
Checklist
Description
When consuming from a cluster or topic that stores messages in the legacy MessageSet format (
log.message.format.version< 0.11, MsgVersion v0..v1), every message is delivered to the application with NULL key and NULL value: fetches succeed and offsets advance, but all payloads are NULL. Offsets and timestamps are correct. The consumer also raises errors such as:Bisected to 6867b9f ("Fetch RPC prework: upgrade to v15", #4584, v2.5.0): since Fetch v12+ the response buffer is parsed as a flexible version, and the legacy MessageSet reader reads Message Key/Value with
rd_kafka_buf_read_kbytes(), which switches to compact (varint) length parsing for flexible-version buffers. Legacy MessageSets always use fixed-width int32 length prefixes, so the first0x00length byte parses as a compact NULL and the reader drifts into the message bytes (theMagicByte 97above is a payload byte). On v2.5.x fetches fail/stall instead; from v2.6.0 onwards messages are delivered with NULL key/value as described. Still present on v2.15.0/master.Found in production through node-rdkafka 3.6.1 (librdkafka 2.12.0), consuming from Apache Kafka 3.9.1 brokers that pin
log.message.format.version=0.10.2.2for rolling-upgrade compatibility.How to reproduce
Run any broker with
log.message.format.version=0.10.2.2(e.g. Apache Kafka 3.9 in ZooKeeper mode withinter.broker.protocol.version=0.10.2.2), produce keyed messages, consume them: all messages arrive with NULL key/value. The fix PR adds a mock-broker regression test (0187) that reproduces this by capping the ProduceRequest version to <= v2 so the producer writes MsgVersion v1/v0 MessageSets.Checklist
inter.broker.protocol.version=0.10.2.2,log.message.format.version=0.10.2.2auto.offset.reset=earliestUnsupported Message(Set) MagicByte 97 at offset 1525458452426752(_NOT_IMPLEMENTED) on every fetchDumpLogSegments)