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-700 — DescribeCluster

Status: implemented — back to the KIP index.

What the KIP changes in Apache Kafka

Kafka 2.8 added the DescribeCluster API (key 60) to give AdminClient.describeCluster() a request of its own. Until then it asked Metadata for the cluster id, the controller, and the broker list, and paid for every topic in the cluster to find out — on a large cluster that response is megabytes of per-partition rows the caller throws away. The new key answers exactly the three facts, plus an optional ClusterAuthorizedOperations bitfield saying what the calling principal may do at cluster scope.

Kafka 3.7 serves v0–v1 (4.0 adds v2). v1 is KIP-919: the request names the endpoint type it wants (1 = brokers, 2 = controllers) so a client bootstrapped against a KRaft controller quorum can tell it apart from a broker, and two error codes become valid at the top level — MISMATCHED_ENDPOINT_TYPE (114) and UNSUPPORTED_ENDPOINT_TYPE (115).

How kaas implements it

  • The codec (crates/kaas-codec/src/api/describe_cluster.rs) serves v0–v2. This is the one key that is flexible from v0 — it postdates KIP-482 entirely, so there is no legacy encoding branch and no version below which the tagged-field blocks disappear.
  • v2 (KIP-1073, Kafka 4.0) is served as a deliberate parity-target exception: it carries IncludeFencedBrokers / IsFenced, and kaas grew a real fenced state to report — see broker fencing. Clients that request fenced brokers unconditionally also need a version where the field is legal, or they fail to encode their own request.
  • The handler (crates/kaas-broker/src/handlers/describe_cluster.rs) shares its broker catalog with Metadata (crates/kaas-broker/src/listener_advert.rs): same per-listener port, same peer FQDNs, same controller derived from the applied assignment.json. Two discovery APIs that disagreed about which port to hand back would loop an authed client on SASL retry, which is why the rule lives in one place rather than two.
  • ClusterAuthorizedOperations is computed only when the client asks for it, and only after Describe on the cluster resource passes. The three answers are distinct on the wire: -2147483648 ("didn't ask"), 0 ("asked, denied"), and the bitfield otherwise.
  • kaas serves broker endpoints only. Controller election runs on a Kubernetes Lease, not a KRaft quorum (Non-goals), so there is no controller endpoint to describe: a v1 request for one answers MISMATCHED_ENDPOINT_TYPE, anything unrecognised UNSUPPORTED_ENDPOINT_TYPE.
  • Two fields kaas cannot answer the way Apache does: Rack is always null (no rack awareness — there are no replicas to place), and the bitfield never sets ClusterAction or IdempotentWrite, because kaas's authorizer models neither operation. Both are detailed on the DescribeCluster reference.
  • IsFenced comes from EndpointSlice readiness rather than a KRaft registration + session timeout, so a booting broker reads as fenced until takeover completes — the same answer Apache gives for a registered broker that hasn't caught up.

How it's verified

  • Codec round trips per version in crates/kaas-codec/src/api/describe_cluster.rs, including the v1-gated endpoint-type field and the i32::MIN "not requested" sentinel.
  • Handler tests in crates/kaas-broker/src/handlers/describe_cluster.rs cover the per-listener broker catalog, both endpoint-type errors, and all three authorized-operations answers.
  • The DescribeCluster leg of bins/kaas/tests/smoke.rs drives a real v1 request through the dispatcher over TCP — the path where a wrong header entry in the registry would misparse every request, since there is no non-flexible version to fall back to.
  • scripts/kafka-cluster.sh runs the real kafka-cluster.sh cluster-id against a live broker, which is an AdminClient.describeCluster() call.