エラーメッセージ
javax.net.ssl.SSLHandshakeException: (unrecognized_name) Received fatal alert: unrecognized_name
別の表記
- Received fatal alert: unrecognized_name
JDK 25 は「(unrecognized_name) Received fatal alert: unrecognized_name」と報告します。Java 7 と初期の Java 8 のリリースは、サーバーがこのアラートを単なる警告として送った場合でも処理を中止していました。一致する ServerName がない Apache httpd の設定でよく起きた、典型的な問題です。
Java (JSSE) — TLS alert 112 from a server that does not serve the requested SNI name
このエラーの意味
JVM は URL のホスト名を SNI として送信しましたが、サーバーにはその名前に対応するサイトが設定されていないため、サーバーは TLS アラート 112(unrecognized_name)を致命的なアラートとして返しました。Java はこのアラートを致命的なものとして扱い、処理を停止します。サーバーには到達できています。使用した名前をサーバーが認識していないだけです。
発生する理由
サーバーにその名前のサイトがない
よくある新しい DNS 名(またはプラットフォームや CDN への CNAME)が、その名前が追加されていないサーバーを指しています。
クライアントが、サーバーに登録されていないエイリアスを使っている
よくあるクライアントの設定に含まれる内部の名前やレガシーな名前のうち、サーバーの仮想ホストに含まれていないものが該当します。
一致する ServerName がない Apache httpd
ときどきTLS の仮想ホストの ServerName と ServerAlias のどれも SNI の名前と一致しない場合、Apache は unrecognized_name を送信します。
修正方法
- 1.
サーバーが受け入れる名前を調べる
openssl s_client -servername を使って、候補となる名前でハンドシェイクを試してください。
bash # Which SNI names does the server accept? for n in api.example.com www.example.com; do printf '%-18s ' "$n" echo | openssl s_client -connect api.example.com:443 -servername "$n" -brief 2>&1 | grep -m1 -E 'Protocol version|alert' || echo fail done - 2.
サーバーにその名前を追加する
ServerName または ServerAlias(あるいは nginx、CDN、プラットフォームでの同等の設定)を、その名前に対応する証明書とあわせて設定してください。
text # Apache httpd: every name clients use must be a ServerName or ServerAlias of a TLS vhost <VirtualHost *:443> ServerName api.example.com ServerAlias api-legacy.example.com SSLEngine on </VirtualHost> - 3.
設定済みのホスト名を使う
SNI を全体で無効にするよりも、URL を修正するほうを優先してください。
text Use the server's configured host name in the URL. Turning SNI off with -Djsse.enableSNIExtension=false only works if the server's default site is the one you need, and it breaks every server that relies on SNI; avoid it.