apache/kafka · error · ConfigException
When the security.protocol configuration enables SASL…
Error message
When the security.protocol configuration enables SASL, mechanism must be non-null and non-empty string.
What it means
ConfigException thrown by CommonClientConfigs.postValidateSaslMechanismConfig when the security.protocol is SASL_PLAINTEXT or SASL_SSL but sasl.mechanism is null or empty. The post-validation runs after the config is parsed, ensuring a SASL-enabled protocol always has a concrete mechanism to negotiate. This is a fail-fast guard against an incomplete SASL setup.
Solutions
- Set sasl.mechanism to a supported value, e.g. 'SCRAM-SHA-512', 'PLAIN', 'GSSAPI', or 'OAUTHBEARER'.
- Ensure the matching jaas config and login handler are configured for that mechanism.
- If you did not intend SASL, set security.protocol back to PLAINTEXT or SSL.
- Verify the override chain (global vs producer/consumer/admin) actually sets the mechanism.
Example fix
# before security.protocol=SASL_SSL # sasl.mechanism missing # after security.protocol=SASL_SSL sasl.mechanism=SCRAM-SHA-512 sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \ username="user" password="secret";
Defensive patterns
Strategy: validation
Validate before calling
SecurityProtocol sp = SecurityProtocol.forName(config.getString(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG)); String mech = config.getString(SaslConfigs.SASL_MECHANISM); if ((sp == SecurityProtocol.SASL_PLAINTEXT || sp == SecurityProtocol.SASL_SSL) && (mech == null || mech.isEmpty())) throw new ConfigException(SaslConfigs.SASL_MECHANISM, null, "SASL protocol requires a non-empty mechanism");
Try / catch
try { CommonClientConfigs.postValidateSaslMechanismConfig(config); } catch (ConfigException e) { if (e.message.contains('mechanism must be non-null')) { /* set sasl.mechanism */ } else throw e; } Prevention
- Whenever security.protocol is SASL_*, also set sasl.mechanism.
- Keep security.protocol and sasl.mechanism in the same config block to avoid partial overrides.
- Include a JAAS config matching the chosen mechanism.
When it happens
Trigger: At line 322, after reading security.protocol and sasl.mechanism, if the protocol is one of the two SASL variants and clientSaslMechanism is null/empty, throw ConfigException naming SASL_MECHANISM. Triggered by setting security.protocol=SASL_SSL/SASL_PLAINTEXT without sasl.mechanism.
Common situations: Switching from PLAINTEXT/SSL to SASL_SSL and forgetting sasl.mechanism; jaas config present but mechanism missing; templated config that leaves mechanism blank; mechanism supplied only in a client-specific override that did not apply.
Related errors
- Failed to create new NetworkClient
- Illegal MetadataRecoveryStrategy: null
- Invalid port in bootstrap.servers
- Invalid port in bootstrap.servers
- Invalid url in bootstrap.servers
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/1dd0b72df100a5c6.
Report an issue: GitHub.
Appendix: source
Thrown at clients/src/main/java/org/apache/kafka/clients/CommonClientConfigs.java:322
RETRY_BACKOFF_MAX_MS_CONFIG, retryBackoffMaxMs, retryBackoffMaxMs);
}
long connectionSetupTimeoutMs = config.getLong(SOCKET_CONNECTION_SETUP_TIMEOUT_MS_CONFIG);
long connectionSetupTimeoutMaxMs = config.getLong(SOCKET_CONNECTION_SETUP_TIMEOUT_MAX_MS_CONFIG);
if (connectionSetupTimeoutMs > connectionSetupTimeoutMaxMs) {
log.warn("Configuration '{}' with value '{}' is greater than configuration '{}' with value '{}'. " +
"A static connection setup timeout with value '{}' will be applied.",
SOCKET_CONNECTION_SETUP_TIMEOUT_MS_CONFIG, connectionSetupTimeoutMs,
SOCKET_CONNECTION_SETUP_TIMEOUT_MAX_MS_CONFIG, connectionSetupTimeoutMaxMs, connectionSetupTimeoutMaxMs);
}
}
public static void postValidateSaslMechanismConfig(AbstractConfig config) {
SecurityProtocol securityProtocol = SecurityProtocol.forName(config.getString(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG));
String clientSaslMechanism = config.getString(SaslConfigs.SASL_MECHANISM);
if (securityProtocol == SecurityProtocol.SASL_PLAINTEXT || securityProtocol == SecurityProtocol.SASL_SSL) {
if (clientSaslMechanism == null || clientSaslMechanism.isEmpty()) {
throw new ConfigException(SaslConfigs.SASL_MECHANISM, null, "When the " + CommonClientConfigs.SECURITY_PROTOCOL_CONFIG +
" configuration enables SASL, mechanism must be non-null and non-empty string.");
}
}
}
public static List<MetricsReporter> metricsReporters(AbstractConfig config) {
return metricsReporters(Collections.emptyMap(), config);
}
public static List<MetricsReporter> metricsReporters(String clientId, AbstractConfig config) {
return metricsReporters(Collections.singletonMap(CommonClientConfigs.CLIENT_ID_CONFIG, clientId), config);
}
public static List<MetricsReporter> metricsReporters(Map<String, Object> clientIdOverride, AbstractConfig config) {
return config.getConfiguredInstances(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG,
MetricsReporter.class, clientIdOverride);
}
View on GitHub (pinned to 996fb4585a)