エラーメッセージ
Client network socket disconnected before secure TLS connection was established
別の表記
- code: 'ECONNRESET'
fetch() では「TypeError: fetch failed」の原因として現れます。npm と yarn は、独自の「request to … failed」というメッセージの中にこれを出力します。同じ文言でもコードが異なる場合(たとえば ETIMEDOUT)は、リセットではなくタイムアウトを示しています。
Node.js tls / https / fetch — code ECONNRESET during the TLS handshake
このエラーの意味
Node.js が ClientHello を送信した後、TLS ハンドシェイクが完了する前に、相手側(または途中にある何か)によって TCP 接続が閉じられました。TLS アラートは届いていないため、Node.js には理由がわかりません。そのため、コード ECONNRESET のリセットとして報告します。原因は証明書ではなく、サーバー、プロキシ、ファイアウォールのいずれかにあります。
発生する理由
社内プロキシが必須なのに使われていない(または設定が誤っている)
よくある外向きの HTTPS をプロキシ経由でしか許可しないネットワークでは、TCP の接続は成功させたうえで、ハンドシェイクを破棄することがよくあります。Node.js はデフォルトでは HTTPS_PROXY を読み込まないため、ブラウザーでは動作するツールがここでは失敗します。
ファイアウォールや TLS フィルターがハンドシェイクを破棄している
よくある次世代ファイアウォールは SNI や TLS フィンガープリントに基づいてブロックし、単に接続を閉じます。VPN クライアントや DNS フィルタリングも同じことをする場合があります。
サーバーが、対応できないハンドシェイクで接続を閉じている
ときどき一部のサーバーやロードバランサーは、SNI がない場合、名前が不明な場合、または一致するプロトコルバージョンがない場合に、アラートを送信せずに接続を閉じます。
過負荷、レート制限、接続数の上限
ときどき接続数の上限に達したサーバーや、上流のレートリミッターは、新しい接続をリセットします。この場合、エラーは負荷がかかったときに断続的に発生します。
修正方法
- 1.
プロキシ設定を確認する
環境変数の設定を、ブラウザーが使っている設定(多くの場合は PAC ファイル)と比較してください。プロキシの URL は通常 http:// にすべきです。また、社内のホストは NO_PROXY に含めてください。
bash env | grep -i -E '^(https?|no)_proxy=' npm config get proxy; npm config get https-proxy # Proxy URL with http:// and internal hosts in NO_PROXY export HTTPS_PROXY=http://proxy.example.net:3128 NO_PROXY=localhost,127.0.0.1,.internal.example.com - 2.
openssl s_client でハンドシェイクを再現する
s_client でも接続が切断される場合、問題はネットワークかサーバーにあります。SNI を変えて、サーバーが SNI を必要としているかどうかを確認してください。
bash # Same handshake without Node.js: does the server or network cut it too? openssl s_client -connect api.example.com:443 -servername api.example.com -brief </dev/null openssl s_client -connect api.example.com:443 -noservername -brief </dev/null - 3.
Node.js にプロキシの環境変数を使わせる
最近の Node.js のリリースでは、NODE_USE_ENV_PROXY=1 を設定すると、http、https、fetch で HTTP_PROXY、HTTPS_PROXY、NO_PROXY が反映されます。axios、got、undici の ProxyAgent などのライブラリには、独自のプロキシオプションがあります。
bash # Node.js does not use HTTPS_PROXY by itself; recent releases can be told to NODE_USE_ENV_PROXY=1 HTTPS_PROXY=http://proxy.example.net:3128 node app.js
関連するエラー
[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocolPython ssl module (OpenSSL)code: 'ERR_SSL_WRONG_VERSION_NUMBER'Node.js tls.connect / fetch (undici)javax.net.ssl.SSLHandshakeException: Remote host terminated the handshakeJava (JSSE)error:0A000126:SSL routines::unexpected eof while readingOpenSSL 3