Сообщение об ошибке
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
Что это означает
Другая сторона (или какой-то узел на пути) закрыла TCP-соединение после того, как Node.js отправил свой ClientHello, и до того, как завершилось TLS-рукопожатие. Оповещение 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, чтобы понять, нужен ли он серверу.
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 учитывают HTTP_PROXY, HTTPS_PROXY и NO_PROXY для http, https и fetch, если задано NODE_USE_ENV_PROXY=1; у библиотек вроде axios, got или ProxyAgent из undici собственные параметры прокси.
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