{"id":"72d77fb43338eb9b","repo":"apache/kafka","slug":"sasl-reconfiguration-failed-due-to-e","errorCode":null,"errorMessage":"SASL reconfiguration failed due to ${e}","messagePattern":"SASL reconfiguration failed due to (.+?)","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/network/SaslChannelBuilder.java","lineNumber":198,"sourceCode":"            }\n        } catch (Throwable e) {\n            close();\n            throw new KafkaException(e);\n        }\n    }\n\n    @Override\n    public Set<String> reconfigurableConfigs() {\n        return securityProtocol == SecurityProtocol.SASL_SSL ? SslConfigs.RECONFIGURABLE_CONFIGS : Set.of();\n    }\n\n    @Override\n    public void validateReconfiguration(Map<String, ?> configs) throws ConfigException {\n        if (this.securityProtocol == SecurityProtocol.SASL_SSL)\n            try {\n                sslFactory.validateReconfiguration(configs);\n            } catch (IllegalStateException e) {\n                throw new ConfigException(\"SASL reconfiguration failed due to \" + e);\n            }\n    }\n\n    @Override\n    public void reconfigure(Map<String, ?> configs) {\n        if (this.securityProtocol == SecurityProtocol.SASL_SSL)\n            sslFactory.reconfigure(configs);\n    }\n\n    @Override\n    public ListenerName listenerName() {\n        return listenerName;\n    }\n\n    @Override\n    public KafkaChannel buildChannel(String id, SelectionKey key, int maxReceiveSize,\n                                     MemoryPool memoryPool, ChannelMetadataRegistry metadataRegistry) throws KafkaException {\n        TransportLayer transportLayer = null;","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/network/SaslChannelBuilder.java#L180-L216","documentation":"Thrown by SaslChannelBuilder.validateReconfiguration as a ConfigException wrapping the IllegalStateException raised by SslFactory.validateReconfiguration. It only applies to a SASL_SSL listener being dynamically reconfigured (via the AlterConfigs / incremental AlterConfigs API). The library throws because the new SSL settings cannot be applied to the existing listener's SslFactory — typically because the keystore/truststore is missing, the alias is unchanged-but-required, or the factory was never fully initialized.","triggerScenarios":"Issuing an AlterConfigs / kafka-configs --alter on a broker to update ssl.keystore.location / ssl.truststore.location / related SSL props on a SASL_SSL listener, when SslFactory.validateReconfiguration detects the new config is incompatible with the current engine (e.g. keystore file not found, password unset, or keystore type unchanged with no key).","commonSituations":"Rotating broker certificates via dynamic config and pointing ssl.keystore.location to a path the broker can't read; changing only the keystore path without updating its password; using AlterConfigs on a listener whose SSL engine hasn't been created (no connections yet).","solutions":["Verify the new ssl.keystore.location / ssl.truststore.location paths are readable by the broker process and the file format matches ssl.keystore.type.","Ensure ssl.keystore.password / ssl.key.password are also being updated (or already correct) in the same AlterConfigs request.","If the underlying cause is 'SslEngineBuilder has not been initialized', establish a connection on the listener first or restart the broker after the change instead of relying on dynamic reconfiguration.","Read the wrapped IllegalStateException message (the '${e}') in the broker log for the precise missing field."],"exampleFix":"# before: only keystore path supplied -> IllegalStateException\nssl.keystore.location=/new/store.p12\n\n# after: supply path + password + type together\nssl.keystore.location=/new/store.p12\nssl.keystore.password=*****\nssl.keystore.type=PKCS12","handlingStrategy":"try-catch","validationCode":"// Pre-flight: only attempt SSL reconfiguration with valid keystore/truststore paths.\nMap<String, Object> newSslConfigs = /* ... */;\nif (newSslConfigs.containsKey(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG)) {\n    Path ks = Path.of((String) newSslConfigs.get(SslConfigs.SSL_KEYSTORE_LOCATION_CONFIG));\n    if (!Files.isReadable(ks)) throw new ConfigException(\"keystore not readable: \" + ks);\n}\nchannelBuilder.validateReconfiguration(newSslConfigs);","typeGuard":null,"tryCatchPattern":"try {\n    channelBuilder.validateReconfiguration(newConfigs);\n    channelBuilder.reconfigure(newConfigs);\n} catch (ConfigException e) {\n    // IllegalStateException from SslFactory was wrapped; keep the OLD ssl context.\n    log.error(\"SASL/SSL reconfiguration rejected; retaining previous config\", e);\n    alertOperators(e);\n}","preventionTips":["SaslChannelBuilder only reconfigures SSL configs (SslConfigs.RECONFIGURABLE_CONFIGS); do not feed unrelated keys.","Ensure the SslFactory is in a configured state before reconfiguring (not closed / not reconfigured mid-startup).","Validate keystore/truststore file existence and readability before calling validateReconfiguration.","On failure, keep the previous SSL context rather than leaving the channel unconfigured."],"tags":["sasl","ssl","reconfiguration","cert-rotation","config"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}