{"id":"cc7efcdc2648e663","repo":"apache/kafka","slug":"type-principalbuilderclass-getname-is-not-an","errorCode":null,"errorMessage":"Type ${principalBuilderClass.getName()} is not an instance of ${KafkaPrincipalBuilder.class.getName()}","messagePattern":"Type (.+?) is not an instance of (.+?)","errorType":"validation","errorClass":"InvalidConfigurationException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/network/ChannelBuilders.java","lineNumber":229,"sourceCode":"    }\n\n    private static void requireNonNullMode(ConnectionMode connectionMode, SecurityProtocol securityProtocol) {\n        if (connectionMode == null)\n            throw new IllegalArgumentException(\"`mode` must be non-null if `securityProtocol` is `\" + securityProtocol + \"`\");\n    }\n\n    public static KafkaPrincipalBuilder createPrincipalBuilder(Map<String, ?> configs,\n                                                               KerberosShortNamer kerberosShortNamer,\n                                                               SslPrincipalMapper sslPrincipalMapper) {\n        Class<?> principalBuilderClass = (Class<?>) configs.get(BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);\n        final KafkaPrincipalBuilder builder;\n\n        if (principalBuilderClass == null || principalBuilderClass == DefaultKafkaPrincipalBuilder.class) {\n            builder = new DefaultKafkaPrincipalBuilder(kerberosShortNamer, sslPrincipalMapper);\n        } else if (KafkaPrincipalBuilder.class.isAssignableFrom(principalBuilderClass)) {\n            builder = (KafkaPrincipalBuilder) Utils.newInstance(principalBuilderClass);\n        } else {\n            throw new InvalidConfigurationException(\"Type \" + principalBuilderClass.getName() + \" is not \" +\n                    \"an instance of \" + KafkaPrincipalBuilder.class.getName());\n        }\n\n        if (builder instanceof Configurable)\n            ((Configurable) builder).configure(configs);\n\n        return builder;\n    }\n\n}\n","sourceCodeStart":211,"sourceCodeEnd":240,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/network/ChannelBuilders.java#L211-L240","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nclass MyPrincipalBuilder implements PrincipalBuilder { /* old SSL-only API */ }\nprops.put(\"principal.builder.class\", \"com.example.MyPrincipalBuilder\");\n\n// after\nimport org.apache.kafka.common.security.auth.KafkaPrincipalBuilder;\n\nclass MyPrincipalBuilder implements KafkaPrincipalBuilder {\n    @Override public KafkaPrincipal build(AuthenticationContext<?> ctx) { /* ... */ }\n    @Override public void configure(Map<String, ?> configs) { /* ... */ }\n}","handlingStrategy":"type-guard","validationCode":"Class<?> clazz = (Class<?>) configs.get(\n    BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);\nif (clazz != null && !KafkaPrincipalBuilder.class.isAssignableFrom(clazz)) {\n    throw new org.apache.kafka.common.errors.InvalidConfigurationException(\n        clazz.getName() + \" is not a \" + KafkaPrincipalBuilder.class.getName());\n}\nChannelBuilders.createPrincipalBuilder(configs, kerberosShortNamer, sslPrincipalMapper);","typeGuard":"static boolean isPrincipalBuilder(Class<?> c) {\n    return c != null && KafkaPrincipalBuilder.class.isAssignableFrom(c);\n}","tryCatchPattern":"try {\n    ChannelBuilders.createPrincipalBuilder(configs, kerberosShortNamer, sslPrincipalMapper);\n} catch (org.apache.kafka.common.errors.InvalidConfigurationException e) {\n    // \"Type X is not an instance of org.apache.kafka.common.security.auth.KafkaPrincipalBuilder\"\n    // remove the offending class and fall back to DefaultKafkaPrincipalBuilder\n    configs.remove(BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG);\n}","preventionTips":["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.\n        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."],"tags":["security","principal-builder","ssl","sasl","configuration","migration","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}