apache/kafka · error · IllegalArgumentException

Cannot request fenced brokers from controller endpoint

Error message

Cannot request fenced brokers from controller endpoint

What it means

Thrown inside the describeCluster Call's createRequest when the Admin client is bootstrapping against KRaft controllers (usingBootstrapControllers() == true) and DescribeClusterOptions.includeFencedBrokers() is true. The controller endpoint does not serve fenced-broker listings — that information is only available from the broker-side DescribeCluster — so requesting it from a controller is rejected with IllegalArgumentException rather than returning incomplete data.

Source

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

    @Override
    public DescribeClusterResult describeCluster(DescribeClusterOptions options) {
        final KafkaFutureImpl<Collection<Node>> describeClusterFuture = new KafkaFutureImpl<>();
        final KafkaFutureImpl<Node> controllerFuture = new KafkaFutureImpl<>();
        final KafkaFutureImpl<String> clusterIdFuture = new KafkaFutureImpl<>();
        final KafkaFutureImpl<Set<AclOperation>> authorizedOperationsFuture = new KafkaFutureImpl<>();

        final long now = time.milliseconds();
        runnable.call(new Call("listNodes", calcDeadlineMs(now, options.timeoutMs()),
            new LeastLoadedBrokerOrActiveKController()) {

            private boolean useMetadataRequest = false;

            @Override
            AbstractRequest.Builder<?> createRequest(int timeoutMs) {
                if (!useMetadataRequest) {
                    if (metadataManager.usingBootstrapControllers() && options.includeFencedBrokers()) {
                        throw new IllegalArgumentException("Cannot request fenced brokers from controller endpoint");
                    }
                    return new DescribeClusterRequest.Builder(new DescribeClusterRequestData()
                        .setIncludeClusterAuthorizedOperations(options.includeAuthorizedOperations())
                        .setEndpointType(metadataManager.usingBootstrapControllers() ?
                            EndpointType.CONTROLLER.id() : EndpointType.BROKER.id())
                        .setIncludeFencedBrokers(options.includeFencedBrokers()));
                } else {
                    // Since this only requests node information, it's safe to pass true for allowAutoTopicCreation (and it
                    // simplifies communication with older brokers)
                    return new MetadataRequest.Builder(new MetadataRequestData()
                        .setTopics(Collections.emptyList())
                        .setAllowAutoTopicCreation(true)
                        .setIncludeClusterAuthorizedOperations(
                            options.includeAuthorizedOperations()));
                }
            }

            @Override

View on GitHub (pinned to c31c9215e1)

Solutions

  1. If you need fenced-broker listings, use an Admin client configured with bootstrap.servers (broker endpoint), which supports includeFencedBrokers(true).
  2. If you must keep bootstrap.controllers, drop includeFencedBrokers(true) (leave it false/default) on the describeCluster call.
  3. Gate the option on bootstrap mode: only set includeFencedBrokers(true) when the client is broker-bootstrapped.

Example fix

// before - controller-bootstrapped client + fenced brokers
props.put(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG, "ctrl1:9093");
try (Admin admin = Admin.create(props)) {
    admin.describeCluster(new DescribeClusterOptions().includeFencedBrokers(true)) // throws
        .all().get();
}

// after - use a broker-bootstrapped client to list fenced brokers
props.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, "broker1:9092");
try (Admin admin = Admin.create(props)) {
    admin.describeCluster(new DescribeClusterOptions().includeFencedBrokers(true))
        .all().get();
}
Defensive patterns

Strategy: validation

Validate before calling

boolean usingBootstrapControllers = props.containsKey(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG)
    && !String.valueOf(props.get(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG)).isBlank();
DescribeClusterOptions options = new DescribeClusterOptions();
if (usingBootstrapControllers) {
    options.includeFencedBrokers(false); // forced; fenced brokers only via broker endpoint
}
admin.describeCluster(options);

Try / catch

try {
    admin.describeCluster(new DescribeClusterOptions().includeFencedBrokers(true));
} catch (IllegalArgumentException e) {
    // 'Cannot request fenced brokers from controller endpoint'
    log.warn("includeFencedBrokers requires bootstrap.servers; retrying without it");
    admin.describeCluster(new DescribeClusterOptions());
}

Prevention

When it happens

Trigger: Admin configured with bootstrap.controllers, then calling admin.describeCluster(new DescribeClusterOptions().includeFencedBrokers(true)). The createRequest lambda checks metadataManager.usingBootstrapControllers() && options.includeFencedBrokers() and throws before any RPC is sent.

Common situations: Reusing a controller-bootstrapped Admin client for an operational dashboard/health tool that wants to enumerate fenced brokers; code that unconditionally sets includeFencedBrokers(true) on every describeCluster call regardless of bootstrap mode; migrating tooling from broker bootstrap to controller bootstrap without gating the fenced-brokers option.

Related errors


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