何が起きているのか
URLを入力すると、ブラウザが少し待機した後、以下のエラーで失敗します:
This site can't provide a secure connection. ERR_SSL_PROTOCOL_ERROR
ブラウザがTLSハンドシェイクを試みたが、失敗した状態です。原因として考えられるのは:不正な暗号スイート、プロトコルバージョンの不一致、サーバーの設定ミス、またはローカル環境(プロキシ、ファイアウォール、ウイルス対策ソフト)が接続に割り込んでいる場合です。
このエラーが何ではないかを明確にしておきます。ERR_CERT_INVALIDは証明書の問題を意味します。ERR_CONNECTION_REFUSEDはサーバーがダウンしていることを意味します。ERR_SSL_PROTOCOL_ERRORの場合、サーバーには到達できています — 問題はハンドシェイク自体にあります。
デバッグ手順
ステップ1:まずブラウザを切り分ける
同じURLを別のブラウザとプライベート/シークレットウィンドウで開いてみてください。どちらかでは動作するが他では動作しない場合、問題はブラウザ固有のもの(拡張機能、キャッシュデータ、設定など)です。どこでも失敗する場合、問題はサーバーまたはネットワーク経路上にあります。
ステップ2:サーバーに直接接続して調べる
ブラウザを完全に迂回し、opensslを使ってサーバーと直接やり取りします:
# 基本的なTLSハンドシェイクテスト
openssl s_client -connect example.com:443
# 特定のTLSバージョンをテスト
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
# サポートされている暗号スイートを列挙
nmap --script ssl-enum-ciphers -p 443 example.com
openssl s_clientでもハンドシェイクが失敗する場合、ブラウザは問題ではありません。サーバーまたはネットワークを調査してください。
ステップ3:HTTPSが傍受されていないか確認する
企業ファイアウォールやウイルス対策製品(Kaspersky、Avast、Bitdefenderなど)は、一般的にSSLインスペクションを行います。これらはTLS接続を終端し、独自の証明書で再暗号化します。注入された証明書が信頼されていない場合、またはTLS 1.3のネゴシエーションが傍受によって破壊された場合、ERR_SSL_PROTOCOL_ERRORが発生します。
# Linux/macOS: 実際に受信している証明書の発行者を確認する
openssl s_client -connect example.com:443 | openssl x509 -noout -issuer -subject
発行者がウイルス対策ベンダーや社内CAを示しており、Let's EncryptやDigiCertのようなものではない場合、通信が傍受されています。
解決策
修正1:SSLステートとブラウザキャッシュをクリアする
古いSSLセッションデータが新しいハンドシェイクの試みを妨害することがあります。クリアしてください。
Chrome:
1. chrome://settings/privacy → 閲覧データの削除 へ移動
2. 「キャッシュされた画像とファイル」と「Cookie」にチェックを入れる
3. 次に chrome://net-internals/#hsts へ移動 → 該当するドメインエントリがあれば削除する
Windows(システムレベルのSSLキャッシュ):
certutil -URLCache * delete
macOS:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
修正2:ウイルス対策ソフトのSSLスキャンをオフにする
これは家庭環境・企業環境で最もよく効く修正方法です。代表的な3製品での設定箇所を示します:
Kaspersky: 設定 → ネットワーク → 暗号化された接続のスキャン → 暗号化された接続をスキャンしないを選択(またはサイトを例外として追加)。
Avast: メニュー → 設定 → 保護 → コアシールド → Webシールド → HTTPSスキャンを有効にするのチェックを外す。
Bitdefender: 保護 → オンライン脅威防止 → 暗号化されたWebスキャンをオフにする。
設定後すぐにページをリロードしてください。読み込めた場合、原因が特定できたことになります。
修正3:ChromeでTLSバージョンを強制する(テスト用のみ)
サーバーが古いTLSのみをサポートしており、ブラウザがそのバージョンを廃止している場合、一時的に接続できるようになります:
# TLS 1.0以上を許可してChromeを起動(本番環境では使用しないこと)
chrome --ssl-version-min=tls1
Chrome 84(2020年7月リリース)以降、TLS 1.0および1.1はデフォルトで無効になっています。chrome://flagsから「TLS」を検索して、何が有効になっているか確認することもできます。ただし、サーバーを管理している場合は、ブラウザをダウングレードするのではなく、サーバー側のTLS設定をアップグレードしてください。ブラウザのダウングレードは短期的な診断手段であり、修正ではありません。
修正4:サーバー側のTLS設定を修正する(サーバーを管理している場合)
nginx:
server {
listen 443 ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/ssl/certs/your_cert.pem;
ssl_certificate_key /etc/ssl/private/your_key.pem;
}
sudo nginx -t && sudo systemctl reload nginx
Apache:
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
sudo apache2ctl configtest && sudo systemctl reload apache2
修正5:システムクロックを同期する
TLS証明書には厳密な有効期間があります。システムクロックが10〜15分ずれているだけで、ハンドシェイクが静かに失敗することがあります。まず確認してみてください — 見落としがちですが、簡単に解決できます。
# Linux
timedatectl status
sudo timedatectl set-ntp true
# macOS
sudo sntp -sS time.apple.com
# Windows(管理者として実行)
w32tm /resync /force
修正6:DNSをフラッシュしてネットワークスタックをリセットする
# Windows(管理者として実行 — 実行後に再起動)
ipconfig /flushdns
netsh winsock reset
netsh int ip reset
# Linux
sudo systemd-resolve --flush-caches
# macOS
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
修正が成功したか確認する
# TLSハンドシェイクが完了することを確認
curl -v https://example.com 2>&1 | grep -E '(SSL|TLS|cipher|certificate)'
# ネゴシエートされたTLSバージョンを確認
curl -v --tlsv1.2 https://example.com 2>&1 | grep 'SSL connection'
# 期待される出力:
# * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
curlが成功してTLSバージョンが表示されていますか?ハンドシェイクは機能しています。ブラウザでURLを開いてみてください — アドレスバーに鍵マークが表示されていれば完了です。
重要なポイント
- ウイルス対策ソフトのSSLスキャンが最も一般的な原因です(家庭・職場環境において)。サーバー側に何も変更がないのにエラーが突然発生した場合は、ここから調査を始めてください。
- **TLS 1.0および1.1は廃止されています。**これらのバージョンのみを提供するサーバーは、すべての最新ブラウザから拒否されます。TLS 1.2が最低要件であり、TLS 1.3が推奨です。
- **システムクロックのズレはHTTPSを静かに破壊します。**TLS検証は設計上、時刻に敏感です。最初に確認すべき項目の一つですが、多くの人が最後まで気づかないことが多いです。
openssl s_clientは最強の診断ツールです — ブラウザのポリシーを迂回して、サーバーが何を提供しているかを正確に表示します。

