{"record":{"id":"8f5b33ce2497f3c9","repo":"apache/pulsar","slug":"client-unable-to-authenticate-with-tls-certificate","errorCode":null,"errorMessage":"Client unable to authenticate with TLS certificate","messagePattern":"Client unable to authenticate with TLS certificate","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTls.java","lineNumber":111,"sourceCode":"                // CN=Steve Kille,O=Isode Limited,C=GB\n                Certificate[] certs = authData.getTlsCertificates();\n                if (null == certs) {\n                    errorCode = ErrorCode.INVALID_CERTS;\n                    throw new AuthenticationException(\"Failed to get TLS certificates from client\");\n                }\n                String distinguishedName = ((X509Certificate) certs[0]).getSubjectX500Principal().getName();\n                for (String keyValueStr : distinguishedName.split(\",\")) {\n                    String[] keyValue = keyValueStr.split(\"=\", 2);\n                    if (keyValue.length == 2 && \"CN\".equals(keyValue[0]) && !keyValue[1].isEmpty()) {\n                        commonName = keyValue[1];\n                        break;\n                    }\n                }\n            }\n\n            if (commonName == null) {\n                errorCode = ErrorCode.INVALID_CN;\n                throw new AuthenticationException(\"Client unable to authenticate with TLS certificate\");\n            }\n            authenticationMetrics.recordSuccess();\n        } catch (AuthenticationException exception) {\n            incrementFailureMetric(errorCode);\n            throw exception;\n        }\n        return commonName;\n    }\n\n}\n","sourceCodeStart":93,"sourceCodeEnd":122,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTls.java#L93-L122","documentation":"AuthenticationProviderTls.authenticate() parses the subject DN of the client's X.509 certificate and uses the CN as the authenticated role. It throws this AuthenticationException when no CN could be extracted (commonName == null) — the certificate exists but its subject has no usable CommonName, so the client's role cannot be determined.","triggerScenarios":"Calling authenticate() with a certificate whose X.509 subject DN contains no CN attribute, or an empty CN — the distinguishedName split finds no 'CN=<value>' pair.","commonSituations":"Generating client certificates with only O/OU fields and no CN; using SAN-only certificates without CN; certificates issued by an internal CA with a custom subject template.","solutions":["Issue the client certificate with a non-empty CN in the subject (this CN becomes the auth role)","Alternatively enable the topic-level authorization mapping via DN if CN is intentionally absent (configure tlsCommonNameRequiredEquivalent or use a different auth provider)","Verify with openssl x509 -noout -subject that the cert actually contains CN="],"exampleFix":"// before: cert subject without CN\nopenssl req -new -subj \"/O=Acme\" -key client.key -out client.csr\n// after: include CN\nopenssl req -new -subj \"/CN=admin/O=Acme\" -key client.key -out client.csr","handlingStrategy":"validation","validationCode":"X509Certificate x509 = (X509Certificate) certs[0];\nString cn = x509.getSubjectX500Principal().getName();\nif (!cn.contains(\"CN=\")) {\n    throw new AuthenticationException(\"Certificate subject has no CN\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    role = provider.authenticate(authData);\n} catch (AuthenticationException e) {\n    log.warn(\"TLS auth failed: certificate has no CN; inspect with openssl x509 -noout -subject\", e);\n}","preventionTips":["Issue client certs with a non-empty CN matching the desired Pulsar role","Validate cert templates in your CA before deployment","Check cert subjects as part of CI/deployment checks"],"tags":["tls","certificate","authentication"],"backgroundTag":"certificate-missing-common-name","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}