apache/kafka · error · IllegalArgumentException
`contextType` must be non-null if `securityProtocol` is `${s
Error message
`contextType` must be non-null if `securityProtocol` is `${securityProtocol}` What it means
Thrown by `ChannelBuilders.clientChannelBuilder` when the security protocol is SASL_PLAINTEXT or SASL_SSL but the `contextType` argument (a `JaasContext.Type`) is null. SASL channels need a JAAS login context to authenticate, and in client mode the caller must say whether to load the CLIENT jaas config or the SERVER (inter-broker) one. Null contextType would cause an NPE deeper in JaasContext loading, so Kafka rejects it at the entry point.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/network/ChannelBuilders.java:74
* @param clientSaslMechanism SASL mechanism if mode is CLIENT, ignored otherwise
* @param time the time instance
* @param logContext the log context instance
*
* @return the configured `ChannelBuilder`
* @throws IllegalArgumentException if `mode` invariants described above is not maintained
*/
public static ChannelBuilder clientChannelBuilder(
SecurityProtocol securityProtocol,
JaasContext.Type contextType,
AbstractConfig config,
ListenerName listenerName,
String clientSaslMechanism,
Time time,
LogContext logContext) {
if (securityProtocol == SecurityProtocol.SASL_PLAINTEXT || securityProtocol == SecurityProtocol.SASL_SSL) {
if (contextType == null)
throw new IllegalArgumentException("`contextType` must be non-null if `securityProtocol` is `" + securityProtocol + "`");
if (clientSaslMechanism == null)
throw new IllegalArgumentException("`clientSaslMechanism` must be non-null in client mode if `securityProtocol` is `" + securityProtocol + "`");
}
return create(securityProtocol, ConnectionMode.CLIENT, contextType, config, listenerName, false, clientSaslMechanism,
null, null, time, logContext, null);
}
/**
* @param listenerName the listenerName
* @param isInterBrokerListener whether or not this listener is used for inter-broker requests
* @param securityProtocol the securityProtocol
* @param config server config
* @param credentialCache Credential cache for SASL/SCRAM if SCRAM is enabled
* @param tokenCache Delegation token cache
* @param time the time instance
* @param logContext the log context instance
* @param apiVersionSupplier supplier for ApiVersions responses sent prior to authentication
*View on GitHub (pinned to c31c9215e1)
Solutions
- Pass `JaasContext.Type.CLIENT` for normal clients (or `JausContext.Type.SERVER` for inter-broker client connections).
- Prefer the high-level `KafkaProducer`/`KafkaConsumer`/`AdminClient` APIs which derive contextType from configs rather than calling clientChannelBuilder directly.
- If writing a custom ChannelBuilder entry point, guard contextType before calling clientChannelBuilder.
Example fix
// before
ChannelBuilders.clientChannelBuilder(
SecurityProtocol.SASL_SSL, null, config, null, "SCRAM-SHA-512", time, logContext);
// after
ChannelBuilders.clientChannelBuilder(
SecurityProtocol.SASL_SSL, JaasContext.Type.CLIENT, config, null, "SCRAM-SHA-512", time, logContext); Defensive patterns
Strategy: validation
Validate before calling
boolean isSasl = securityProtocol == SecurityProtocol.SASL_PLAINTEXT
|| securityProtocol == SecurityProtocol.SASL_SSL;
if (isSasl && contextType == null) {
throw new IllegalArgumentException(
"contextType required for securityProtocol " + securityProtocol);
}
ChannelBuilders.clientChannelBuilder(
securityProtocol, contextType, config, listenerName, clientSaslMechanism, time, logContext); Try / catch
try {
ChannelBuilders.clientChannelBuilder(
securityProtocol, contextType, config, listenerName,
clientSaslMechanism, time, logContext);
} catch (IllegalArgumentException e) {
// "`contextType` must be non-null if `securityProtocol` is SASL_*"
if (securityProtocol == SecurityProtocol.SASL_PLAINTEXT
|| securityProtocol == SecurityProtocol.SASL_SSL) {
contextType = JaasContext.Type.CLIENT;
}
} Prevention
- Pair every SASL_* securityProtocol with a non-null JaasContext.Type when calling clientChannelBuilder.
- Derive contextType from the security protocol in one helper so SASL never reaches the builder without a type.
- Treat null contextType as valid only for PLAINTEXT/SSL; assert the SASL=>non-null invariant in config validation.
When it happens
Trigger: Calling `ChannelBuilders.clientChannelBuilder(SASL_PLAINTEXT|SASL_SSL, null, config, listenerName, clientSaslMechanism, time, logContext)` — i.e. contextType is null while the protocol is SASL_*. Hit internally by Kafka client bootstrap (Admin/Producer/Consumer) when assembling the channel builder from client configs.
Common situations: A custom client wrapper that constructs a SASL channel but forgets to pass `JaasContext.Type.CLIENT`. Migrating a PLAINTEXT client to SASL without updating the bootstrap code. Framework integration (Spring/Quarkus) that injects null for the JAAS context type. Inter-broker or tooling code that only conditionally sets contextType.
Related errors
- `clientSaslMechanism` must be non-null in client mode if `se
- `mode` must be non-null if `securityProtocol` is `${security
- Type ${principalBuilderClass.getName()} is not an instance o
- Failed to create new NetworkClient
- When the security.protocol configuration enables SASL, mecha
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/a11561801d437c47.json.
Report an issue: GitHub.