Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

KIP-800 — Join/leave reason strings

Status: implemented — back to the KIP index.

What the KIP changes in Apache Kafka

Kafka 3.1 added a nullable reason string to JoinGroup requests (v8) and to each member entry in LeaveGroup requests (v5), so clients can tell the broker why they are rejoining or leaving ("the consumer is being closed", rebalance triggered by metadata change, …). It is a request-side-only, diagnostics-oriented field: Apache logs it to make rebalance storms explainable.

How kaas implements it

  • crates/kaas-codec/src/api/join_group.rs decodes the nullable reason on v8+ requests (kaas serves JoinGroup v2–v9, flexible from v6); crates/kaas-codec/src/api/leave_group.rs decodes the per-member reason on v5+ (kaas serves v0–v5, flexible from v4). Both are version-gated exactly per the Apache 3.7 schema — v7/v4 wire bytes must not contain the field, and the encoders enforce that.
  • This field earned its regression fixture the hard way: the pre-fix v5 LeaveGroup decoder read the reason's length byte as the tagged-field count, which broke every modern Java client's clean shutdown (the consumer sends "the consumer is being closed" on close). The fixture test in leave_group.rs pins the literal bytes a Java 3.7 client sends.
  • The broker decodes the reason and then discards it. Neither handler (crates/kaas-broker/src/handlers/join_group.rs, leave_group.rs) nor the group coordinator (crates/kaas-coordinator/src/group.rs) logs, stores, or acts on it — there is no occurrence of the field beyond the codec layer. Wire parity is what "implemented" means here; surfacing the reason in broker logs/metrics, which is the KIP's operational payoff, is honest follow-up work.

Since clients enable this unconditionally at v8/v5, the load-bearing part is accepting the field without corrupting the rest of the request — which is exactly where the old bug lived.

How it's verified

  • crates/kaas-codec/src/api/leave_group.rs: v5_java_client_fixture_with_reason (captured Java-client bytes, reason "bye", null group_instance_id) and v4_omits_reason_on_the_wire (the field must not leak into v4 encodings).
  • crates/kaas-codec/src/api/join_group.rs: v8_adds_reason round-trips the field at v8+.
  • scripts/kafka-consumer-groups.sh and scripts/kafka-console-consumer.sh run modern Java clients through full join → consume → clean-close cycles, which send reason strings on every leave.

See also the JoinGroup and LeaveGroup entries in the per-API reference.