はじめに
先日突然、Chromeで特定のWebページにだけアクセスできない事象が発生しました。
同じネットワーク環境でSafariでは全サイト正常にアクセスできたため、Chrome固有の問題であることは早期に特定できました。しかし原因究明にはかなり時間がかかりました。
本記事では事象の詳細・発生理由・解決策を記録します。同じ症状で困っている方の参考になれば幸いです。
事象
症状
Webサイトアクセス時、Chromeで以下のエラーが表示され、特定のサイトにアクセスできない状態になりました。
このサイトにアクセスできません
https://example-site.com のウェブページは一時的に停止している
か、新しいウェブアドレスに移動した可能性があります。
ERR_ADDRESS_INVALID
またこの時、アクセスできるサイトとできないサイトが混在している状況でした。
調査過程
今回の調査では、問題の範囲を段階的に絞り込む手順で進めました。
ping → ネットワーク・DNSは正常か? → ✅ 正常
curl → TCP接続(HTTPS)はできるか? → ❌ 失敗
↓
Chrome固有の問題ではなく、OS側のTCP通信が原因
① pingは正常に通る
まず「そもそもサーバーまで通信が届いているか」を確認するためにpingを使いました。pingはネットワーク疎通確認の最も基本的なコマンドで、DNSの名前解決(ドメイン→IPアドレスの変換)とICMPパケットの到達確認が同時にできます。
$ ping example-site-a.com
PING example-site-a.com (xxx.xxx.xxx.xxx): 56 data bytes
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=54 time=14.148 ms
64 bytes from xxx.xxx.xxx.xxx: icmp_seq=1 ttl=54 time=18.715 ms
pingが通るため、DNS・ネットワーク自体の問題ではないことが分かります。
② curlではエラーが発生する
次に「Chromeと同じHTTPS通信(TCP port 443)ができるか」を確認するためにcurlを使いました。ブラウザの問題を切り分けるために、Chrome以外のツールで同じ通信を再現してみることが目的です。
$ curl -v https://example-site-a.com 2>&1 | head -30
* Trying xxx.xxx.xxx.xxx:443...
* Immediate connect fail for xxx.xxx.xxx.xxx: Can't assign requested address
* Failed to connect to example-site-a.com port 443 after 16 ms: Couldn't connect to server
curl: (7) Failed to connect to example-site-a.com port 443 after 16 ms: Couldn't connect to server
curlでも同じエラーが発生したことで「Chromeのバグではなく、OS側のTCP通信に問題がある」と絞り込むことができました。Can't assign requested address というエラーから、TCP接続(port 443)ができない状態であることが判明しました。
発生理由
原因:ネットワークソケットの枯渇
原因はネットワークソケットの枯渇でした。
ネットワークソケットとは、OSがネットワーク通信を管理するために発行する「接続ハンドル」のようなものです。TCPで通信するためには必ずソケットが必要で、OSが管理できるソケット数には上限があります。
OSのソケット管理上限:例)1000個
ゾンビソケット:1000個(解放されずに残り続ける)
使える空き :0個
↓
新しいソケットを作れない
↓
「Can't assign requested address」
なぜソケットが枯渇したのか
PCをスリープにすると、通信中のソケットが中途半端な状態で凍結されます。復帰後にOSがソケットを解放するはずが、何らかの理由で失敗し、ゾンビソケットとして残り続けました。これを繰り返すうちに上限に達しました。
スリープ前:ソケット接続中
↓
スリープ(通信が途切れる)
↓
復帰後:OSがソケットを解放しようとする
↓
解放失敗 → ゾンビソケットとして残り続ける
↓
これを繰り返す → 上限に達する → 新しいソケットが作れない
pingは通るのにcurlが通らなかった理由
pingは ICMP(Internet Control Message Protocol) というプロトコルを使用しており、ソケットを必要としません。そのためソケットが枯渇していてもpingは正常に動作します。
| コマンド | プロトコル | ソケット使用 | 結果 |
|---|---|---|---|
| ping | ICMP | 不要 | ✅ 通った |
| curl / Chrome | TCP | 必要 | ❌ 失敗 |
アクセスできるサイトとできないサイトが混在していた理由
ソケットが完全に枯渇していたわけではなく、上限付近まで使用されている状態でした。
この状態では、新規にソケットを確保する必要がある通信は失敗する一方で、既存のソケットを再利用できる通信は成功するため、結果としてサイトごとにアクセス可否の差が発生します。
さらに、ゾンビ化したソケットが多数残っていたことで新規ソケットの確保が困難になり、この差が顕著になっていました。
解決策
⚠️ 本記事はMac環境での事例です。Windowsでも同様の現象は起こりえますが、確認・対処コマンドが異なります。
即時解決:PCを再起動する
再起動するとOS上のソケットがすべてリセットされ、ゾンビソケットもすべて解放されます。
再起動なしで試す場合
# ネットワークインターフェースを再起動
sudo ifconfig en0 down
sudo ifconfig en0 up
ソケットの状況を確認するコマンド
# 現在のソケット一覧
netstat -an
# 状態別に確認(ゾンビソケットの確認)
netstat -an | grep TIME_WAIT # 通信終了後の後処理中
netstat -an | grep CLOSE_WAIT # 相手が切断済みで自分がまだ閉じていない
# ソケット総数を確認
netstat -an | wc -l
TIME_WAIT や CLOSE_WAIT が大量に表示される場合はソケット枯渇の兆候です。異常値の目安は環境によりますが、数千件以上あれば要注意です。
まとめ
| 項目 | 内容 |
|---|---|
| 原因 | ネットワークソケットの枯渇 |
| 引き金 | スリープ・復帰を繰り返す中でのゾンビソケットの蓄積 |
| 解決策 | PCの再起動 |
| 予防策 | 定期的な再起動・netstat でのソケット状況監視 |
ChromeのみでSafariは正常だった点については、SafariとChromeでソケットの管理方法が異なる可能性もありますが、根本原因はOS側のソケット枯渇です。
同様の症状が出た場合は、まず netstat -an | wc -l でソケット数を確認し、異常に多い場合は再起動を試みてください。