OpenSSL「wrong version number」の原因と直し方
wrong version number は、URL の http と https をポートに合わせるか、サーバーの listen に ssl を付ければ直る。
TLS で話しかけた相手が平文で応答すると出るエラーで、curl の (35) も同じ原因である。
公開:
要約
wrong version number は、TLS で話しかけた相手から TLS ではない応答が返ったときに OpenSSL が出すエラーである。
名前から TLS のバージョンの不一致を疑いやすいが、多くは平文で待ち受けているポートへ TLS で接続していることが原因である。curl -k は証明書の検証を切るだけなので、付けても同じエラーのまま変わらない。
OpenSSL を使うツールごとに、同じ原因が次のように表示される。
| 実行したもの | 表示 |
|---|---|
| curl 8.14・OpenSSL 3.5 | curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version number |
| curl 7.88・OpenSSL 3.0 | curl: (35) OpenSSL/3.0.22: error:0A00010B:SSL routines::wrong version number |
| curl 8.5・OpenSSL 1.1.1 | curl: (35) OpenSSL/1.1.1w: error:1408F10B:SSL routines:ssl3_get_record:wrong version number |
| Python 3.13 の urllib | [SSL: WRONG_VERSION_NUMBER] wrong version number |
| Node.js 22 の fetch | ERR_SSL_WRONG_VERSION_NUMBER |
nginx の proxy_pass https:// | SSL_do_handshake() failed (SSL: error:0A00010B:SSL routines::wrong version number) |
相手のポートが TLS を話しているかどうかは、openssl s_client で分かる。
openssl s_client -connect example.com:443 </dev/nullTLS のポートなら、subject= の行と New, TLSv1.3 のような行が出る。
平文のポートなら wrong version number と no peer certificate available が出る。
解決策
1. スキームとポートを合わせる
同じポートに http:// で接続して通常の応答が返るなら、そのポートは平文で待ち受けている。
curl -sS http://example.com:443/通常の応答が返ったら、URL を http:// に直すか、TLS を待ち受けているポートへ接続先を変える。
TLS のポートへ http:// で接続した場合は、nginx なら 400 The plain HTTP request was sent to HTTPS port が返るので区別できる。
2. nginx の listen に ssl を付ける
server {
listen 443 ssl;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
}nginx -s reload のあと、openssl s_client で subject= の行が出ることを確かめる。
3. HTTPS_PROXY を http:// で始める
HTTPS_PROXY は「HTTPS の通信に使うプロキシ」を指す変数で、プロキシ自身のスキームは別に決まる。
平文で待ち受けるプロキシなら http:// で書く。
export HTTPS_PROXY=http://proxy.example.com:88884. STARTTLS のポートには -starttls を付ける
-starttls を付けると、s_client がプロトコルごとの手順を踏んでから TLS へ切り替える。
openssl s_client -connect mail.example.com:587 -starttls smtp </dev/nullよくある原因
https://の URL で平文のポートへ接続している。https://example.com:80や、HTTP で動かしている開発サーバーのポートへの接続で起きる。- nginx の
listen 443;にsslが無い。
証明書を書いていても、sslが無ければそのポートは平文の HTTP で応答する。 HTTPS_PROXYの値がhttps://で始まっている。
プロキシとの間の通信まで TLS になるので、平文の応答を返すプロキシに対してはこのエラーになる。
tinyproxy のように何も返さないプロキシでは、エラーにならずタイムアウトになる。- SMTP の 587 番のように、平文で始めて途中から TLS に切り替えるポートへ、最初から TLS で接続している。
サーバーの最初の挨拶が平文なので、ここでも同じエラーになる。