{"record":{"id":"4049993b63bce745","repo":"apache/cassandra","slug":"mutualtlswithpasswordfallbackauthenticator-require","errorCode":null,"errorMessage":"MutualTlsWithPasswordFallbackAuthenticator requires client_encryption_options.require_client_auth to be optional/true","messagePattern":"MutualTlsWithPasswordFallbackAuthenticator requires client_encryption_options\\.require_client_auth to be optional/true","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java","lineNumber":87,"sourceCode":"    public SaslNegotiator newSaslNegotiator(InetAddress clientAddress, Certificate[] certificates)\n    {\n        if (certificates == null || certificates.length == 0)\n        {\n            // If no certificates present, fallback to PasswordAuthentication\n            return newSaslNegotiator(clientAddress);\n        }\n        // Otherwise attempt to authenticate using the client-provided certificate.\n        return mutualTlsAuthenticator.newSaslNegotiator(clientAddress, certificates);\n    }\n\n    @Override\n    public void validateConfiguration() throws ConfigurationException\n    {\n        Config config = DatabaseDescriptor.getRawConfig();\n        if (config.client_encryption_options.getClientAuth() == EncryptionOptions.ClientEncryptionOptions.ClientAuth.NOT_REQUIRED)\n        {\n            String msg = \"MutualTlsWithPasswordFallbackAuthenticator requires client_encryption_options.require_client_auth to be optional/true\";\n            throw new ConfigurationException(msg);\n        }\n    }\n}\n","sourceCodeStart":69,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/MutualTlsWithPasswordFallbackAuthenticator.java#L69-L91","documentation":"Thrown as a ConfigurationException when MutualTlsWithPasswordFallbackAuthenticator is configured but client_encryption_options.require_client_auth is NOT_REQUIRED. This authenticator needs client certificates to be at least optional so it can attempt mTLS authentication before falling back to password.","triggerScenarios":"Selecting MutualTlsWithPasswordFallbackAuthenticator as the authenticator while client_encryption_options has require_client_auth: false (ClientAuth NOT_REQUIRED).","commonSituations":"Enabling the fallback authenticator on the native-transport (client) side without turning on client certificate enforcement; upgrading configs where require_client_auth defaulted to false.","solutions":["Set client_encryption_options.require_client_auth: true (or optional) in cassandra.yaml","Ensure client_encryption_options.enabled is true so the setting takes effect","Restart the node"],"exampleFix":"// before\nclient_encryption_options:\n  enabled: true\n  require_client_auth: false\n// after\nclient_encryption_options:\n  enabled: true\n  require_client_auth: optional","handlingStrategy":"validation","validationCode":"# require_client_auth must be optional/true when using the fallback authenticator\ngrep 'require_client_auth' cassandra.yaml","typeGuard":null,"tryCatchPattern":"try { authenticator.validateConfiguration(); }\ncatch (ConfigurationException e) { LOG.error(\"client_encryption_options misconfigured: \" + e.getMessage()); throw e; }","preventionTips":["Enable client encryption and set require_client_auth before choosing this authenticator","Keep client_encryption_options and authenticator choice in one config-management template"],"tags":["tls","mtls","configuration","client-authentication"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}