apache/kafka · error · MismatchedEndpointTypeException

Expected response from CONTROLLER endpoint, but got response

Error message

Expected response from CONTROLLER endpoint, but got response from endpoint type {endpointType}

What it means

Thrown by KafkaAdminClient.parseDescribeClusterResponse when a DescribeCluster response indicates it came from an endpoint whose type is not CONTROLLER, while the client expected a controller response (this path is taken when bootstrapping/operating against KRaft controllers). The MismatchedEndpointTypeException signals that the cluster metadata handshake routed the request to a broker-style endpoint instead of a controller, so the response cannot be trusted as controller-authoritative.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java:1808

                    metadataManager.updateFailed(e);
                    return false;
                }

                @Override
                public void handleFailure(Throwable e) {
                    metadataManager.updateFailed(e);
                }
            };
        }
    }

    static Cluster parseDescribeClusterResponse(DescribeClusterResponseData response) {
        ApiError apiError = new ApiError(response.errorCode(), response.errorMessage());
        if (apiError.isFailure()) {
            throw apiError.exception();
        }
        if (response.endpointType() != EndpointType.CONTROLLER.id()) {
            throw new MismatchedEndpointTypeException("Expected response from CONTROLLER " +
                "endpoint, but got response from endpoint type " + (int) response.endpointType());
        }
        List<Node> nodes = new ArrayList<>();
        Node controllerNode = null;
        for (DescribeClusterResponseData.DescribeClusterBroker node : response.brokers()) {
            Node newNode = new Node(node.brokerId(), node.host(), node.port(), node.rack());
            nodes.add(newNode);
            if (node.brokerId() == response.controllerId()) {
                controllerNode = newNode;
            }
        }
        return new Cluster(response.clusterId(),
            nodes,
            Collections.emptyList(),
            Collections.emptySet(),
            Collections.emptySet(),
            controllerNode);
    }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Verify bootstrap.controllers host:port values target the controller listener (typically port 9093 / the KRaft controller listener), not the broker listener.
  2. If you actually want broker-side metadata, use bootstrap.servers instead of bootstrap.controllers.
  3. Check cluster health: ensure KRaft controllers are elected and reachable, and that no load balancer/proxy is rewriting the connection to a broker.
  4. Confirm client and broker versions are compatible for the DescribeCluster API version in use.

Example fix

// before - controller ports actually point at brokers
props.put(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG, "host1:9092,host2:9092");
Admin admin = Admin.create(props);
admin.describeCluster().all().get(); // MismatchedEndpointTypeException

// after - point at the KRaft controller listener
props.put(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG, "host1:9093,host2:9093");
Admin admin = Admin.create(props);
admin.describeCluster().all().get();
Defensive patterns

Strategy: retry

Try / catch

int attempts = 0;
while (true) {
    try {
        DescribeClusterResult r = admin.describeCluster(opts).nodes().get();
        break;
    } catch (ExecutionException e) {
        if (e.getCause() instanceof MismatchedEndpointTypeException && attempts++ < 3) {
            continue; // broker returned wrong endpoint type; retry after metadata refresh
        }
        throw e;
    }
}

Prevention

When it happens

Trigger: describeCluster (or internal metadata refresh) issued against a bootstrap.controllers-configured Admin client where the server returned a DescribeClusterResponse with endpointType != EndpointType.CONTROLLER.id; happens inside the call's handleResponse -> parseDescribeClusterResponse when the active node is not advertising itself as a controller.

Common situations: bootstrap.controllers pointing at broker ports instead of KRaft controller listener ports; mixed-version cluster during upgrade where some nodes don't populate endpointType correctly; network/LB in front of the cluster routing controller-bound traffic to a broker; pointing an old client at a new cluster or vice versa where the DescribeCluster V# endpoint-type field semantics differ.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/0ee1155059c3cd02.json. Report an issue: GitHub.