{"record":{"id":"da5be9009f76725a","repo":"alibaba/canal","slug":"failed-to-retrieve-the-common-name-cn-from-the-s","errorCode":null,"errorMessage":"Failed to retrieve the Common Name (CN) from the server certificate.","messagePattern":"Failed to retrieve the Common Name \\(CN\\) from the server certificate\\.","errorType":"exception","errorClass":"CertificateException","httpStatus":null,"severity":"critical","filePath":"driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java","lineNumber":300,"sourceCode":"                }\n\n                // verify server certificate identity\n                if (this.hostName != null) {\n                    logger.info(\"verify hostName: {}\", this.hostName);\n                    Set<String> expectHostNames = new HashSet<>();\n                    for (X509Certificate certificate : chain) {\n                        String dn = certificate.getSubjectX500Principal().getName(X500Principal.RFC2253);\n                        String cn = null;\n                        try {\n                            LdapName ldapDN = new LdapName(dn);\n                            for (Rdn rdn : ldapDN.getRdns()) {\n                                if (rdn.getType().equalsIgnoreCase(\"CN\")) {\n                                    cn = rdn.getValue().toString();\n                                    break;\n                                }\n                            }\n                        } catch (InvalidNameException e) {\n                            throw new CertificateException(\n                                \"Failed to retrieve the Common Name (CN) from the server certificate.\");\n                        }\n                        expectHostNames.add(cn);\n                    }\n\n                    if (!expectHostNames.contains(this.hostName)) {\n                        throw new CertificateException(\n                            \"Server certificate identity check failed. The certificate Common Name \"\n                                                       + expectHostNames.stream()\n                                                           .map(h -> \"'\" + h + \"'\")\n                                                           .collect(Collectors.joining(\", \"))\n                                                       + \" does not match with '\" + this.hostName + \"'.\");\n                    }\n\n                }\n            }\n        }\n","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/driver/src/main/java/com/alibaba/otter/canal/parse/driver/mysql/socket/BioSocketChannelPool.java#L282-L318","documentation":"Thrown inside checkServerTrusted during VERIFY_IDENTITY hostname matching when LdapName parsing of the certificate subject DN raises InvalidNameException. The code extracts the CN from the RFC2253-formatted subject; if that string violates LDAP naming rules (malformed DN, escaping issues, non-RFC2253 content), parsing aborts and the wrapper cannot obtain a CN to compare against hostName.","triggerScenarios":"VERIFY_IDENTITY mode with a server certificate whose subject DN is not parseable as an LDAP name under RFC2253 (e.g. odd attribute types, broken escaping, or a DN the LdapName class rejects). Triggered during the TLS handshake identity check.","commonSituations":"Self-signed or custom-CA cert with an unusual DN format; a certificate whose CN uses characters that break RFC2253 parsing; a CA tool that emitted a non-standard subject; JVM version differences in LDAP DN parsing strictness.","solutions":["Regenerate the server certificate with a standard CN subject (e.g. CN=host.example.com,O=...).","Verify the subject DN with openssl x509 -noout -subject and confirm it is RFC2253-compliant.","If the cert cannot be changed, fall back to SslMode.VERIFY_CA (which skips hostname matching).","Ensure the cert uses standard attribute types (CN, O, OU, C)."],"exampleFix":"# before (cert subject malformed)\n# subject=BadDN(with parens)\n# -> InvalidNameException at handshake\n\n# after (regenerate with standard subject)\nopenssl req -new -key server.key -subj \"/CN=mysql.internal.example.com/O=Example\" -out server.csr","handlingStrategy":"validation","validationCode":"// Pre-validate the cert subject DN parses as LDAP before enabling VERIFY_IDENTITY\njavax.naming.ldap.LdapName n = new javax.naming.ldap.LdapName(\n    cert.getSubjectX500Principal().getName(javax.security.auth.x500.X500Principal.RFC2253));","typeGuard":null,"tryCatchPattern":"try {\n    socketFactory.createSocket(...).startHandshake();\n} catch (javax.net.ssl.SSLHandshakeException e) {\n    Throwable c = e.getCause();\n    if (c instanceof java.security.cert.CertificateException\n        && c.getMessage().contains(\"Common Name\")) {\n        // regenerate cert with a standard CN, or use VERIFY_CA\n    }\n    throw e;\n}","preventionTips":["Issue server certs with a standard CN subject (CN=host.example.com).","Validate the DN parses as RFC2253/LdapName before relying on VERIFY_IDENTITY.","Keep DN attribute types standard (CN, O, OU, C)."],"tags":["network","ssl","tls","certificate","hostname","ldap","security"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}