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
- Verify bootstrap.controllers host:port values target the controller listener (typically port 9093 / the KRaft controller listener), not the broker listener.
- If you actually want broker-side metadata, use bootstrap.servers instead of bootstrap.controllers.
- Check cluster health: ensure KRaft controllers are elected and reachable, and that no load balancer/proxy is rewriting the connection to a broker.
- 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
- This is a server-side protocol mismatch (DescribeCluster answered with a non-CONTROLLER endpoint) — usually transient or broker-version-related; retry with backoff.
- If it persists, switch the client from bootstrap.controllers to bootstrap.servers, or upgrade the broker to a version whose DescribeCluster honors the requested endpoint type.
- Do not treat it as a programmer error; it surfaces from parseDescribeClusterResponse, not from caller input.
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
- Cannot request fenced brokers from controller endpoint
- You cannot set both bootstrap.servers and bootstrap.controll
- You must set either bootstrap.servers or bootstrap.controlle
- Failed to create new KafkaAdminClient
- The specified value of default.api.timeout.ms must be no sma
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/0ee1155059c3cd02.json.
Report an issue: GitHub.