apache/kafka · error · ConfigException

You cannot set both bootstrap.servers and bootstrap.controll

Error message

You cannot set both bootstrap.servers and bootstrap.controllers

What it means

Thrown by KafkaAdminClient.determineBootstrapType when both bootstrap.servers and bootstrap.controllers are non-empty in the same Admin config. The client must commit to a single bootstrap path so AdminMetadataManager and the NetworkClient know which endpoint type to target for initial metadata; specifying both is ambiguous, so construction fails fast with a ConfigException.

Source

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

        }
        List<String> controllerServers = config.getList(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG);
        if (controllerServers == null) {
            controllerServers = Collections.emptyList();
        }

        if (bootstrapServers.isEmpty()) {
            if (controllerServers.isEmpty()) {
                throw new ConfigException("You must set either " +
                    CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG + " or " +
                    AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG);
            } else {
                return true; // Using bootstrap.controllers
            }
        } else {
            if (controllerServers.isEmpty()) {
                return false; // Using bootstrap.servers
            } else {
                throw new ConfigException("You cannot set both " +
                    CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG + " and " +
                    AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG);
            }
        }
    }

    static KafkaAdminClient createInternal(AdminClientConfig config, TimeoutProcessorFactory timeoutProcessorFactory) {
        return createInternal(config, timeoutProcessorFactory, null);
    }

    static KafkaAdminClient createInternal(
        AdminClientConfig config,
        TimeoutProcessorFactory timeoutProcessorFactory,
        HostResolver hostResolver
    ) {
        Metrics metrics = null;
        NetworkClient networkClient = null;
        Time time = Time.SYSTEM;

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Keep bootstrap.servers only if you want to bootstrap against brokers (the common case for most clients).
  2. Keep bootstrap.controllers only if you intentionally want to bootstrap directly against KRaft controllers, and remove bootstrap.servers.
  3. Audit config files, env vars, and Spring/Quarkus property sources to ensure only one bootstrap key is set.
  4. If both must coist in different deployments, drive selection from a single profile/env var so only one key is non-empty at runtime.

Example fix

// before
Map<String, Object> cfg = new HashMap<>();
cfg.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, "broker1:9092");
cfg.put(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG, "ctrl1:9093");
Admin admin = Admin.create(cfg); // throws ConfigException

// after - pick ONE bootstrap source
Map<String, Object> cfg = new HashMap<>();
cfg.put(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, "broker1:9092");
// bootstrap.controllers intentionally omitted
Admin admin = Admin.create(cfg);
Defensive patterns

Strategy: validation

Validate before calling

boolean hasServers = props.containsKey(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG)
    && !String.valueOf(props.get(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG)).isBlank();
boolean hasControllers = props.containsKey(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG)
    && !String.valueOf(props.get(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG)).isBlank();
if (hasServers && hasControllers) {
    throw new IllegalArgumentException("Set only ONE of bootstrap.servers or bootstrap.controllers, not both");
}
Admin admin = Admin.create(props);

Try / catch

try {
    Admin admin = Admin.create(props);
} catch (ConfigException e) {
    // 'You cannot set both bootstrap.servers and bootstrap.controllers'
    log.error("Conflicting bootstrap config", e);
}

Prevention

When it happens

Trigger: Calling Admin.create with a config that contains both CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG and AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG each resolving to a non-empty list (e.g. broker endpoints in bootstrap.servers and KRaft controller endpoints in bootstrap.controllers).

Common situations: Migrating a cluster to KRaft and leaving the old bootstrap.servers value in place while also adding bootstrap.controllers; shared config templates that set both keys; copy-paste from examples that merge broker-only and controller-only snippets; environment overlays that append one key without clearing the other.

Related errors


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