ERR_SSL_VERSION_OR_CIPHER_MISMATCHの修正:古いサーバーでサポートされていないTLSバージョン

intermediate🔒 SSL/TLS2026-04-21| Webサーバー(Apache 2.2〜2.4、Nginx 1.x)、Node.js、OpenSSL 1.1.1未満、ブラウザ(Chrome、Firefox、Edge)、Linux/Windows/macOS

Error Message

ERR_SSL_VERSION_OR_CIPHER_MISMATCH — The client and server don't support a common SSL protocol version or cipher suite.
#ssl#tls#バージョン#暗号スイート

TL;DR

サーバーがTLS 1.0またはTLS 1.1を使用しています。モダンブラウザは2020年初頭に両方のサポートを打ち切りました — Chrome 84とFirefox 74がいずれも対応を終了しています。TLS 1.2/1.3を有効にして古いバージョンを無効化すれば完了です。

# Nginx — サーバーブロックまたはhttpブロックに追記する
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

変更後にNginxをリロードする: sudo systemctl reload nginx

このエラーの意味

ERR_SSL_VERSION_OR_CIPHER_MISMATCHは、ページのデータが1バイトも転送される前にTLSハンドシェイクが失敗したときに表示されます。原因は主に3つあります:

  • サーバーがTLS 1.0またはTLS 1.1しか提供していない。Chrome 84(2020年8月)とFirefox 74(2020年3月)はいずれもこれらのサポートを削除しました。
  • サーバー上のすべての暗号スイートが安全でないと判断され、モダンクライアントから除外されている。
  • SSL証明書のCommon Nameがドメイン名と一致していない — まれなケースですが、同じエラーコードが表示されます。

ほとんどの場合、2014年頃に設定されてそのまま放置されたサーバーが原因です。古い設定、新しいブラウザ、ハンドシェイク失敗という流れです。

現在のTLS設定を確認する

設定を変更する前に、サーバーが実際にアドバタイズしている内容を確認しましょう:

# opensslがインストールされているLinuxマシンから実行する
openssl s_client -connect yourdomain.com:443 -tls1
openssl s_client -connect yourdomain.com:443 -tls1_1
openssl s_client -connect yourdomain.com:443 -tls1_2
openssl s_client -connect yourdomain.com:443 -tls1_3

-tls1-tls1_1では接続できるのに-tls1_2で失敗する場合 — それが問題の原因です。暗号スイートの詳細を確認するにはnmapの方が手軽です:

nmap --script ssl-enum-ciphers -p 443 yourdomain.com

詳細なグレード評価レポートが必要ですか?SSL Labs Server Test(「ssllabs server test」で検索)を実行してください。サポートされているすべてのプロトコルが一覧表示され、非推奨のものには赤いFマークが付きます。

Nginxでの修正

Nginxの設定ファイルを開きます — 通常は/etc/nginx/nginx.conf/etc/nginx/sites-available/配下のサイト設定ファイルです。SSLブロックを見つけて次のように置き換えます:

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # 既存のssl_protocolsの行をこれに置き換える:
    ssl_protocols TLSv1.2 TLSv1.3;

    # モダンな暗号リスト — 脆弱な暗号を除外する
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
}
# 設定をテストしてからリロードする
nginx -t
sudo systemctl reload nginx

Apacheでの修正

バーチャルホストの設定ファイルか/etc/apache2/mods-enabled/ssl.confを編集します。重要なディレクティブはSSLProtocolです — マイナス記号で古いバージョンを明示的に無効化します:

<VirtualHost *:443>
    ServerName yourdomain.com
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem

    # 古いプロトコルを無効化する
    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

    # モダンな暗号スイートのみ使用する
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLHonorCipherOrder off
</VirtualHost>
# 設定を確認して再起動する
apache2ctl configtest
sudo systemctl restart apache2

Node.js(HTTPSサーバー)での修正

カスタムのNode.js HTTPSサーバーを使っていますか?createServerの呼び出しでTLSオプションを明示的に指定します:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem'),
  minVersion: 'TLSv1.2',   // TLS 1.2未満を拒否する
  ciphers: [
    'ECDHE-RSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-RSA-CHACHA20-POLY1305',
  ].join(':'),
};

https.createServer(options, app).listen(443);

サーバーではなくクライアント側の場合

サードパーティのAPIを呼び出してこのエラーが発生している場合、問題はリモートサーバー側にあります — こちらのサーバーは正常です。対処法は以下の通りです:

  • **APIプロバイダーに連絡する。**TLS 1.2を有効化するよう依頼してください。それが根本的な解決策です。
  • 内部システムで待機中の短期的な回避策が必要な場合、HTTPクライアントでTLS 1.2を明示的に指定できます:
# Python requests — カスタムアダプターでTLS 1.2以上を強制する
import ssl
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context

class TLS12Adapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        ctx = create_urllib3_context()
        ctx.minimum_version = ssl.TLSVersion.TLSv1_2
        kwargs['ssl_context'] = ctx
        super().init_poolmanager(*args, **kwargs)

session = requests.Session()
session.mount('https://', TLS12Adapter())
response = session.get('https://old-api.example.com/endpoint')

本番環境でTLS 1.0/1.1を受け入れるようにクライアントをダウングレードしてはいけません。それでは対策の意味が完全になくなります。

OpenSSLバージョンの確認

TLS 1.3にはOpenSSL 1.1.1以降が必要です。それより古いバージョンではnginx.confに何を書いてもTLS 1.3は利用できません。

openssl version
# TLS 1.3サポートにはOpenSSL 1.1.1以上が必要

OpenSSL 1.0.xのままですか?まずライブラリをアップグレードしてから、サーバーの設定を更新してください:

# Debian/Ubuntuの場合
sudo apt update && sudo apt install openssl libssl-dev

# CentOS/RHEL 8以降の場合
sudo dnf install openssl

修正を確認する

# TLS 1.2が動作することを確認する
openssl s_client -connect yourdomain.com:443 -tls1_2
# 表示されるはず: SSL handshake has read ... bytes
# 確認する内容: Protocol: TLSv1.2

# 古いTLSが拒否されることを確認する
openssl s_client -connect yourdomain.com:443 -tls1_1
# 失敗するはず: alert handshake failure など

# TLS 1.3が動作することを確認する(サポートされている場合)
openssl s_client -connect yourdomain.com:443 -tls1_3

Chromeでサイトを開いてください。エラーが消え、鍵マークが表示されるはずです。鍵マークをクリックして「接続は保護されています」→「証明書は有効です」を確認し、どのプロトコルバージョンが使われているかを確認してください。

証明書のCN不一致(同じエラー、異なる原因)

ホスト名の不一致が原因で一部のブラウザにERR_SSL_VERSION_OR_CIPHER_MISMATCHが表示されることがあります — 紛らわしいことに同じエラーコードです。以下のコマンドで確認できます:

openssl s_client -connect yourdomain.com:443 | openssl x509 -noout -subject -subj_hash
# subject= CN=yourdomain.com

# SANを確認する
openssl s_client -connect yourdomain.com:443 | openssl x509 -noout -text | grep -A1 "Subject Alternative Name"

CNまたは少なくとも1つのSANエントリが、接続しようとしているドメインと一致している必要があります。どちらも一致しない場合は、正しいドメインで証明書を再発行してください。

Related Error Notes