apache/kafka · error · ConfigException
You must set either bootstrap.servers or…
Error message
You must set either bootstrap.servers or bootstrap.controllers
What it means
Thrown by KafkaAdminClient.determineBootstrapType (a ConfigException) when neither bootstrap.servers nor bootstrap.controllers is configured. The Admin client needs at least one entry point to contact the cluster.
Solutions
- Set AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG to a comma-separated host:port list (most common).
- Or set AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG when talking directly to KRaft controllers.
- Log the resolved config map in dev to catch empty/typo'd keys early.
Example fix
// before Map<String, Object> cfg = new HashMap<>(); // bootstrap.servers missing Admin.create(cfg); // after Map<String, Object> cfg = new HashMap<>(); cfg.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "broker1:9092,broker2:9092"); Admin.create(cfg);
Defensive patterns
Strategy: validation
Validate before calling
String servers = (String) props.get(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG);
String controllers = (String) props.get(AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG);
if ((servers == null || servers.isEmpty()) && (controllers == null || controllers.isEmpty())) {
throw new IllegalStateException("Configure bootstrap.servers or bootstrap.controllers");
} Try / catch
try {
Admin.create(props);
} catch (ConfigException e) {
if (e.getMessage().contains("bootstrap")) { /* fix config, retry */ }
} Prevention
- Always set one bootstrap property in shared config templates.
- Log the resolved config in dev to catch empty/typo'd keys.
When it happens
Trigger: Building an Admin with a Properties/Map that omits both CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG and AdminClientConfig.BOOTSTRAP_CONTROLLERS_CONFIG. Setting the key to an empty string. Reading config from a file where the property was commented out.
Common situations: Copy-pasting an Admin config block and dropping the bootstrap line; property-name typo (e.g. bootstrap.server without the s); env-var substitution that resolved to empty; migrating from bootstrap.servers to bootstrap.controllers but forgetting to actually set the new key.
Related errors
- You cannot set both bootstrap.servers and…
- The specified value of default.api.timeout.ms must be no…
- Cannot request fenced brokers from controller endpoint
- Expected response from CONTROLLER endpoint, but got…
- Failed to create new KafkaAdminClient
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/bbddb220f8535b5f.
Report an issue: GitHub.
Appendix: source
Thrown at clients/src/main/java/org/apache/kafka/clients/admin/KafkaAdminClient.java:544
* Validates that exactly one of bootstrap.servers or bootstrap.controllers is configured.
*
* @param config The admin client configuration
* @return true if using bootstrap.controllers, false if using bootstrap.servers
* @throws ConfigException if both or neither bootstrap configurations are set
*/
static boolean determineBootstrapType(AdminClientConfig config) {
List<String> bootstrapServers = config.getList(CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG);
if (bootstrapServers == null) {
bootstrapServers = Collections.emptyList();
}
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);View on GitHub (pinned to 996fb4585a)