错误信息
No subject alternative DNS name matching api.example.com found.
也可能输出为
- javax.net.ssl.SSLHandshakeException: (certificate_unknown) No subject alternative DNS name matching api.example.com found.
- java.security.cert.CertificateException: No subject alternative DNS name matching api.example.com found.
其中的主机就是你 URL 中的主机。JDK 21 和 25 会在前面加上 TLS 告警:“(certificate_unknown) No subject alternative DNS name matching … found.”。完全没有 SAN 扩展的证书,或者使用 IP 地址的 URL,则会分别报出“No subject alternative names present”和“No subject alternative names matching IP address … found”。
Java (JSSE HostnameChecker) — java.security.cert.CertificateException inside SSLHandshakeException
含义
证书链是可信的,但 Java 的主机名检查(HTTPS 端点识别)在证书的主题备用名称(SAN)扩展中没有找到与 URL 中主机匹配的 DNS 条目。消息中会给出 Java 要连接的主机。由于证书带有 SAN 扩展,Java 不会考虑它的通用名称。
原因
证书没有覆盖这个主机名
常见证书是为其他名称签发的(www.、根域名、旧的服务名);通配符只能覆盖一级标签。
客户端使用了内部别名或服务名
常见Kubernetes 服务名、docker-compose 别名和负载均衡器的主机名都能访问到正确的服务器,但它们并不在为公开名称签发的证书中。
服务器返回了另一个站点的证书
偶见在共享端点上,返回哪张证书取决于 SNI;未配置的名称会拿到默认证书。
修复方法
- 1.
列出证书包含的名称
用 openssl 或 keytool -printcert -sslserver 显示 SubjectAlternativeName 条目,再与 URL 对比。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -ext subjectAltName # or with Java's own tool keytool -printcert -sslserver api.example.com:443 | grep -A3 SubjectAlternativeName - 2.
补上缺失的名称,重新签发证书
申请时列出客户端使用的每一个 DNS 名称;keytool 的 -ext SAN=dns:…,dns:… 可以把它们加入 CSR。
bash # Java keystores: request a certificate with every name in the SAN extension keytool -certreq -alias server -keystore server.p12 -ext "SAN=dns:api.example.com,dns:www.example.com" -file server.csr - 3.
使用证书中列出的名称连接
保持主机名验证开启,改为修改 URL(以及名称解析);一律放行的 HostnameVerifier 等于取消了 TLS 本该提供的保护。
java // Use the name in the certificate in the URL; resolve it to the address you need // (DNS, /etc/hosts or a custom resolver), instead of connecting by IP or alias. HttpRequest req = HttpRequest.newBuilder(URI.create("https://www.example.com/health")).build();
相关错误
No subject alternative names matching IP address 127.0.0.1 foundJava (JSSE HostnameChecker)No subject alternative names presentJava (JSSE HostnameChecker)x509: certificate is valid for example.com, not api.example.comGo crypto/x509curl: (60) SSL: no alternative certificate subject name matches target hostname…curl (OpenSSL backend)