{"record":{"id":"fd0c85e84465efb6","repo":"apache/cassandra","slug":"mutualtlsinternodeauthenticator-requires-server-en","errorCode":null,"errorMessage":"MutualTlsInternodeAuthenticator requires server_encryption_options.internode_encryption to be enabled & server_encryption_options.require_client_auth to be true","messagePattern":"MutualTlsInternodeAuthenticator requires server_encryption_options\\.internode_encryption to be enabled & server_encryption_options\\.require_client_auth to be true","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java","lineNumber":176,"sourceCode":"\n    @Override\n    public boolean authenticate(InetAddress remoteAddress, int remotePort, Certificate[] certificates, InternodeConnectionDirection connectionType)\n    {\n        return authenticateInternodeWithMtls(remoteAddress, remotePort, certificates, connectionType);\n    }\n\n\n    @Override\n    public void validateConfiguration() throws ConfigurationException\n    {\n        Config config = DatabaseDescriptor.getRawConfig();\n        if (config.server_encryption_options.internode_encryption == EncryptionOptions.ServerEncryptionOptions.InternodeEncryption.none\n            || config.server_encryption_options.getClientAuth() != REQUIRED)\n        {\n            String msg = \"MutualTlsInternodeAuthenticator requires server_encryption_options.internode_encryption to be enabled\" +\n                         \" & server_encryption_options.require_client_auth to be true\";\n            logger.error(msg);\n            throw new ConfigurationException(msg);\n        }\n    }\n\n    protected boolean authenticateInternodeWithMtls(InetAddress remoteAddress, int remotePort, Certificate[] certificates,\n                                                    IInternodeAuthenticator.InternodeConnectionDirection connectionType)\n    {\n        if (connectionType == IInternodeAuthenticator.InternodeConnectionDirection.INBOUND)\n        {\n            String identity = certificateValidator.identity(certificates);\n            if (!certificateValidator.isValidCertificate(certificates))\n            {\n                noSpamLogger.error(\"Not a valid certificate from {}:{} with identity '{}'\", remoteAddress, remotePort, identity);\n                return false;\n            }\n\n            if (!trustedIdentities.contains(identity))\n            {\n                noSpamLogger.error(\"Unable to authenticate user {}\", identity);","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/MutualTlsInternodeAuthenticator.java#L158-L194","documentation":"Thrown during validateConfiguration() as a ConfigurationException when the authenticator is selected but the server-side encryption settings do not actually enforce mutual TLS. mTLS internode authentication is meaningless unless internode encryption is enabled and client (peer) certificate auth is required.","triggerScenarios":"Setting authenticator/class to MutualTlsInternodeAuthenticator while cassandra.yaml has server_encryption_options.internode_encryption: none, or require_client_auth is false (ClientAuth not REQUIRED).","commonSituations":"Enabling the mTLS authenticator without enabling internode_encryption; leaving require_client_auth commented/false; partial TLS configuration applied only to some nodes.","solutions":["Set server_encryption_options.internode_encryption to dc, rack, or all (not none)","Set server_encryption_options.require_client_auth: true (ClientAuth REQUIRED)","Restart the node so validateConfiguration passes","Ensure the setting is identical on all nodes to avoid mixed-mode failure"],"exampleFix":"// before (cassandra.yaml)\nserver_encryption_options:\n  internode_encryption: none\n  require_client_auth: false\n// after\nserver_encryption_options:\n  internode_encryption: all\n  require_client_auth: true","handlingStrategy":"validation","validationCode":"# before enabling the authenticator, check yaml\n# server_encryption_options.internode_encryption != none AND require_client_auth: true\ngrep -A2 'internode_encryption' cassandra.yaml","typeGuard":null,"tryCatchPattern":"try { authenticator.validateConfiguration(); }\ncatch (ConfigurationException e) { LOG.error(\"Fix server_encryption_options: \" + e.getMessage()); throw e; }","preventionTips":["Enable internode_encryption and require_client_auth together when selecting the mTLS authenticator","Apply identical TLS settings across all nodes via config management","Test configuration in a staging cluster first"],"tags":["tls","mtls","configuration","internode-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"}