Сообщение об ошибке
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 сообщение будет «No subject alternative names present», а для URL с IP-адресом — «No subject alternative names matching IP address … found».
Java (JSSE HostnameChecker) — java.security.cert.CertificateException inside SSLHandshakeException
Что это означает
Цепочка сертификатов доверенная, но проверка имени хоста в Java (идентификация эндпоинта HTTPS) не нашла в сертификате, в расширении альтернативного имени субъекта (SAN), ни одного DNS-имени, совпадающего с хостом из URL. Java приводит в сообщении хост, к которому её попросили подключиться. Поскольку у сертификата есть расширение SAN, его общее имя (CN) не учитывается.
Почему это происходит
Сертификат не покрывает это имя хоста
частоСертификат выпущен на другие имена (www., домен без www, старое имя сервиса); wildcard покрывает только один уровень имени.
Клиент обращается по внутреннему псевдониму или имени сервиса
частоИмена сервисов 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-имена, по которым обращаются клиенты; параметр -ext SAN=dns:…,dns:… в keytool добавляет их в 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)