apache/kafka · error · InvalidConfigurationException
Type ${principalBuilderClass.getName()} is not an instance o
Error message
Type ${principalBuilderClass.getName()} is not an instance of ${KafkaPrincipalBuilder.class.getName()} What it means
Thrown by `ChannelBuilders.createPrincipalBuilder` when the configured `principal.builder.class` is neither null/DefaultKafkaPrincipalBuilder nor assignable to `KafkaPrincipalBuilder`. The broker uses this builder to convert the authenticated peer (SSL DN, SASL name, Kerberos principal) into a `KafkaPrincipal` for authorization; a class that doesn't implement the interface cannot be invoked. Unlike the other entries here, this is an `InvalidConfigurationException` (not IllegalArgumentException), reflecting that it stems from a bad user-supplied config value.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/network/ChannelBuilders.java:229
}
private static void requireNonNullMode(ConnectionMode connectionMode, SecurityProtocol securityProtocol) {
if (connectionMode == null)
throw new IllegalArgumentException("`mode` must be non-null if `securityProtocol` is `" + securityProtocol + "`");
}
public static KafkaPrincipalBuilder createPrincipalBuilder(Map<String, ?> configs,
KerberosShortNamer kerberosShortNamer,
SslPrincipalMapper sslPrincipalMapper) {
Class<?> principalBuilderClass = (Class<?>) configs.get(BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);
final KafkaPrincipalBuilder builder;
if (principalBuilderClass == null || principalBuilderClass == DefaultKafkaPrincipalBuilder.class) {
builder = new DefaultKafkaPrincipalBuilder(kerberosShortNamer, sslPrincipalMapper);
} else if (KafkaPrincipalBuilder.class.isAssignableFrom(principalBuilderClass)) {
builder = (KafkaPrincipalBuilder) Utils.newInstance(principalBuilderClass);
} else {
throw new InvalidConfigurationException("Type " + principalBuilderClass.getName() + " is not " +
"an instance of " + KafkaPrincipalBuilder.class.getName());
}
if (builder instanceof Configurable)
((Configurable) builder).configure(configs);
return builder;
}
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Make your custom class `implements KafkaPrincipalBuilder` (override `build` and `configure`).
- If migrating from the old SSL PrincipalBuilder, wrap or rewrite it as a KafkaPrincipalBuilder (the old interface is removed).
- Remove the `principal.builder.class` config to fall back to `DefaultKafkaPrincipalBuilder`.
- Verify the JAR containing your custom builder is on the broker/client classpath and not shadowed by an older copy.
Example fix
// before
class MyPrincipalBuilder implements PrincipalBuilder { /* old SSL-only API */ }
props.put("principal.builder.class", "com.example.MyPrincipalBuilder");
// after
import org.apache.kafka.common.security.auth.KafkaPrincipalBuilder;
class MyPrincipalBuilder implements KafkaPrincipalBuilder {
@Override public KafkaPrincipal build(AuthenticationContext<?> ctx) { /* ... */ }
@Override public void configure(Map<String, ?> configs) { /* ... */ }
} Defensive patterns
Strategy: type-guard
Validate before calling
Class<?> clazz = (Class<?>) configs.get(
BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);
if (clazz != null && !KafkaPrincipalBuilder.class.isAssignableFrom(clazz)) {
throw new org.apache.kafka.common.errors.InvalidConfigurationException(
clazz.getName() + " is not a " + KafkaPrincipalBuilder.class.getName());
}
ChannelBuilders.createPrincipalBuilder(configs, kerberosShortNamer, sslPrincipalMapper); Type guard
static boolean isPrincipalBuilder(Class<?> c) {
return c != null && KafkaPrincipalBuilder.class.isAssignableFrom(c);
} Try / catch
try {
ChannelBuilders.createPrincipalBuilder(configs, kerberosShortNamer, sslPrincipalMapper);
} catch (org.apache.kafka.common.errors.InvalidConfigurationException e) {
// "Type X is not an instance of org.apache.kafka.common.security.auth.KafkaPrincipalBuilder"
// remove the offending class and fall back to DefaultKafkaPrincipalBuilder
configs.remove(BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);
} Prevention
- Implement org.apache.kafka.common.security.auth.KafkaPrincipalBuilder for any custom principal builder class.
- Old `PrincipalBuilder` (pre-0.10) is not compatible; migrate legacy implementations to KafkaPrincipalBuilder. validate the configured class with isAssignableFrom at config-load time, not at first connection.
- Leave principal.builder.class unset to use DefaultKafkaPrincipalBuilder unless you have a concrete reason to customize.
When it happens
Trigger: Configuring `principal.builder.class` to a fully-qualified class name whose Class is not a subtype of `KafkaPrincipalBuilder`, then starting a broker or constructing a channel that calls `createPrincipalBuilder`. Hit when the class is an old `PrincipalBuilder` (the pre-0.10.2.0 SSL-only interface), a plain `Login` class, or an arbitrary bean.
Common situations: Upgrading from an old Kafka version where `org.apache.kafka.common.security.auth.PrincipalBuilder` (deprecated, SSL-only) was configured; the new API requires `KafkaPrincipalBuilder`. Copying a custom class name from another project without adding the dependency. Typing a class that exists but implements the wrong interface. Classpath shadowing where a stale older version of the class is loaded.
Related errors
- `contextType` must be non-null if `securityProtocol` is `${s
- `clientSaslMechanism` must be non-null in client mode if `se
- `mode` must be non-null if `securityProtocol` is `${security
- Failed to create new KafkaAdminClient
- When the security.protocol configuration enables SASL, mecha
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/cc7efcdc2648e663.json.
Report an issue: GitHub.