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 appliedassignment.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. ClusterAuthorizedOperationsis computed only when the client asks for it, and only afterDescribeon 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 unrecognisedUNSUPPORTED_ENDPOINT_TYPE. - Two fields kaas cannot answer the way Apache does:
Rackis always null (no rack awareness — there are no replicas to place), and the bitfield never setsClusterActionorIdempotentWrite, because kaas's authorizer models neither operation. Both are detailed on the DescribeCluster reference. IsFencedcomes 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 thei32::MIN"not requested" sentinel. - Handler tests in
crates/kaas-broker/src/handlers/describe_cluster.rscover the per-listener broker catalog, both endpoint-type errors, and all three authorized-operations answers. - The DescribeCluster leg of
bins/kaas/tests/smoke.rsdrives 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.shruns the realkafka-cluster.sh cluster-idagainst a live broker, which is anAdminClient.describeCluster()call.