Решение проблем

ERR_CONNECTION_RESET: кто сбросил соединение и что делать

ERR_CONNECTION_RESET: соединение оборвал пакет TCP reset. Если не открывается ни один сайт, проверьте VPN, прокси, антивирус; если один — его сервер и файрвол.

Опубликовано ~10 мин чтения

Коротко: ERR_CONNECTION_RESET значит, что соединение с сайтом было установлено, а затем оборвано пакетом TCP reset (RST), который прислал сервер или что-то между вами и ним. Если не открывается ни один сайт, причина на вашей стороне: VPN, прокси, антивирус или сетевой фильтр. Если один сайт не открывается из любой сети, соединение рвёт его сервер или файрвол перед ним.

В русском Chrome страница выглядит так: заголовок Не удается получить доступ к сайту, под ним Соединение сброшено., затем Попробуйте сделать следующее: со списком Проверьте подключение к интернету., Проверьте настройки прокси-сервера и брандмауэра. и в Windows Выполните диагностику сети в Windows, а внизу код ERR_CONNECTION_RESET. В английском интерфейсе это This site can’t be reached и The connection was reset. Яндекс Браузер, Edge и Opera построены на Chromium и показывают тот же код.

Один запрос из терминала показывает то, что скрывает браузер:

Linux · macOS
curl -sSv -o /dev/null https://example.com/
Windows PowerShell
curl.exe -sSv -o NUL https://example.com/

Замените example.com на сайт, который не открывается. Если за строками запроса (> GET) следует Recv failure: Connection reset by peer (в Windows: Connection was reset), сервер или устройство перед ним приняло запрос и сбросило соединение. Та же строка сразу после Client hello указывает на TLS, причина 5. Если curl работает, а браузер получает сброс, ищите на своём компьютере: настройку прокси, расширение или антивирус, который фильтрует только браузеры. В Linux с русской локалью curl берёт системный текст ошибки, и конец строки будет русским: Recv failure: Соединение разорвано другой стороной.

Какое сообщение вы видите?

ГдеСообщениеЧто произошло
Chrome, EdgeНе удается получить доступ к сайту · Соединение сброшено. · ERR_CONNECTION_RESET (в английском интерфейсе This site can’t be reached · The connection was reset.)После открытия соединения пришёл RST (сетевая ошибка Chromium -101)
Яндекс БраузерERR_CONNECTION_RESETТо же самое: браузер построен на Chromium
FirefoxСоединение было сброшено (The connection was reset)То же событие
curl, HTTPcurl: (56) Recv failure: Connection reset by peerСброс после отправки запроса
curl 7.88, HTTPScurl: (35) Recv failure: Connection reset by peerСброс во время TLS-рукопожатия
PythonConnectionResetError: [Errno 104] Connection reset by peerТо же; 104 — это ECONNRESET в Linux
Node.jsError: read ECONNRESETТо же. socket hang up означает, что сервер корректно закрыл соединение, ничего не ответив
nginx error.logrecv() failed (104: Connection reset by peer) while reading response header from upstreamВаше приложение сбросило соединение с nginx; посетитель получит 502, а не сброс
sshkex_exchange_identification: read: Connection reset by peerВариант для SSH, со своими причинами (fail2ban, MaxStartups)

Строки Chrome, curl, Python и Node — реальный вывод (Chrome 153, Debian 12); русские строки Chrome и Firefox взяты из их файлов перевода. Python и Node пишут по-английски и при LC_ALL=ru_RU.UTF-8, nginx тоже. curl в Linux с русской локалью переводит системную часть сообщения: curl: (56) Recv failure: Соединение разорвано другой стороной. С этой ошибкой путают трёх соседей. ERR_CONNECTION_REFUSED (англ.) — это ответ на самый первый пакет: сброс, потому что порт никто не слушает, или отказ файрвола. ERR_CONNECTION_TIMED_OUT (англ.) значит, что ответа нет вообще. ERR_EMPTY_RESPONSE (в curl: Empty reply from server) значит, что сервер корректно закрыл соединение, ничего не отправив.

Если сообщение пришло от SSH, читайте лучше статью SSH connection reset by peer (англ.).

Не открывается ни один сайт или только один?

КартинаСброс приходит отКуда смотреть
Все сайты, на одном устройствеЭтого устройства: VPN, прокси, антивирус, сломанный сетевой стекВаш компьютер
Все сайты, на всех устройствах в одной сетиРоутера, провайдера или сетевого фильтраПерезагрузите роутер, проверьте через мобильный интернет
Один сайт, из любой сети и с любого устройстваСервера или файрвола перед нимВладельцам сайтов
Один сайт, только из одной сетиЧего-то на этом пути: фильтра провайдера или офиса, MTUВаш компьютер, MTU

Что исправить на своём компьютере

  • Откройте сайт в режиме инкогнито. Он отключает расширения, в том числе прокси- и VPN-дополнения. Очистка кеша и cookie помогает редко: сброс происходит ниже HTTP, где ни то ни другое не участвует.
  • Отключите VPN и любой прокси. В Windows прокси находится в разделе Параметры → Сеть и Интернет → Прокси-сервер, на Mac — в Системные настройки → Сеть → ваше подключение → Подробнее → Прокси. В Яндекс Браузере путь такой: Настройки → Системные → Сеть → Настройки прокси-сервера.
  • Приостановите веб-защиту антивируса. Антивирусы, которые проверяют HTTPS (у «Лаборатории Касперского» эта функция называется «Проверка защищенных соединений»), сами открывают каждое соединение и сбрасывают то, что не смогли разобрать. Если сайт после этого открылся, добавьте его в исключения и снова включите защиту.
  • Попробуйте другую сеть, например точку доступа на телефоне. Если там всё работает, соединение сбрасывает фильтр вашего провайдера, учебного заведения или офиса, обычно после того, как прочитал имя хоста в TLS-рукопожатии (SNI).
  • Старый файрвол и новый браузер. Начиная с Chrome и Edge 124 (апрель 2024 года) TLS ClientHello несёт постквантовый key share и больше не помещается в один пакет. Файрволы и прокси с проверкой TLS на устаревшей прошивке сбрасывают такие соединения. Временная политика Chrome, которая это отключала, перестала действовать в Chrome 146, так что решение — обновить прошивку этого устройства.
  • На телефоне переключитесь между Wi-Fi и мобильным интернетом и отключите VPN-приложение. Если сбрасываются все сайты, но только в одной сети Wi-Fi, перезагрузите роутер.

Если на одном ПК с Windows не открывается ни один сайт, сбросьте его сетевой стек в терминале, запущенном от имени администратора, и перезагрузитесь:

Windows · терминал от имени администратора
netsh winsock reset
netsh int ip reset
ipconfig /flushdns

Чтобы проверить MTU, отправьте полный пакет в 1500 байт, который нельзя фрагментировать (1472 байта данных плюс 28 байт заголовков). Если 1472 не проходит, а на 1400 ответы приходят, какой-то участок пути пропускает только пакеты поменьше. Многие узлы вообще не отвечают на ping, поэтому замените TARGET адресом, который отвечает на маленькие пакеты:

Windows
ping -f -l 1472 TARGET
ping -f -l 1400 TARGET
Linux
ping -c 3 -M do -s 1472 TARGET
ping -c 3 -M do -s 1400 TARGET

Если проблема только у вашего подключения (VPN, PPPoE или мобильный роутер), найдите наибольший размер, на который ещё приходят ответы, прибавьте 28 и задайте это значение как MTU адаптера. Владельцы сайтов исправляют это для всех с помощью MSS clamping.

Windows · терминал от имени администратора
netsh interface ipv4 show subinterfaces
netsh interface ipv4 set subinterface "INTERFACE" mtu=NEW_MTU store=persistent

Владельцам сайтов: кто присылает сброс

Воспроизведите сброс через curl, пока на сервере записываются сбросы на порту 443. VISITOR_IP — адрес, с которого запускается curl; уберите часть с host, чтобы видеть всех клиентов:

Debian · Ubuntu · на сервере
sudo tcpdump -ni any 'tcp port 443 and host VISITOR_IP and tcp[tcpflags] & tcp-rst != 0'

Без фильтра по флагам видно весь обмен; здесь тестовый сервер читает запрос, а затем сбрасывает соединение:

Пример вывода · tcpdump, метки времени и опции убраны
IP 127.0.0.1.34914 > 127.0.0.1.47101: Flags [S], seq 788105413, win 65495, length 0
IP 127.0.0.1.47101 > 127.0.0.1.34914: Flags [S.], seq 3469401065, ack 788105414, win 65483, length 0
IP 127.0.0.1.34914 > 127.0.0.1.47101: Flags [.], ack 1, win 512, length 0
IP 127.0.0.1.34914 > 127.0.0.1.47101: Flags [P.], seq 1:80, ack 1, win 512, length 79
IP 127.0.0.1.47101 > 127.0.0.1.34914: Flags [.], ack 80, win 511, length 0
IP 127.0.0.1.47101 > 127.0.0.1.34914: Flags [R.], seq 1, ack 80, win 512, length 0
  • Flags [R.] уходит с вашего сервера: его отправил ваш сервер. Смотрите причины 1–4 ниже.
  • Клиент получает сброс, а в захвате на сервере RST нет: его подделало устройство посередине — фильтр в сети посетителя, IPS или DDoS-фильтр перед вашим сервером. В захвате на стороне клиента (Wireshark или tcpdump -v) сравните ttl пакета RST с ttl пакета SYN-ACK от вашего сервера: поддельный сброс отправлен с другого узла, и значение обычно отличается.

Наш HTTP Header Checker (англ.) запрашивает URL из Амстердама. Если он получает нормальный ответ, а у одного посетителя сбросы продолжаются, сброс касается только этого посетителя: его маршрута или правила, которое срабатывает на его адрес (причина 3).

Почему посетители редко видят сброс от вашего приложения

Браузер видит только сбросы от машины, с которой разговаривает; всё, что дальше, превращается в ошибку HTTP. Значит, сброс в браузере на сайте за nginx пришёл от nginx или от того, что стоит перед ним:

СхемаКогда приложение сбрасывает соединениеПосетитель видит
Приложение на публичном порту (Node, Gunicorn, бинарник на Go)RST получает браузерERR_CONNECTION_RESET
Перед ним nginx, Apache или CaddyПрокси пишет в лог recv() failed (104: …) или upstream prematurely closed connection502 Bad Gateway
Перед ним прокси CloudflareRST или 502 получает CloudflareОшибку 520 (англ.) или ту же 502

Причина 1: процесс, державший соединение, упал или перестал читать

Когда процесс завершается, ядро закрывает его сокеты, а сокет с непрочитанными данными запроса закрывается сбросом. Сюда относится приложение, убитое OOM killer, падение, перезапуск во время деплоя и сервер приложений, который отклоняет загрузку, не дочитав её. Сначала проверьте:

Debian · Ubuntu
# процесс убит OOM killer или упал?
sudo journalctl -k --since "1 hour ago" | grep -iE 'killed process|segfault'

# перезапуски и ошибки службы самого приложения
systemctl status APP_SERVICE --no-pager
sudo journalctl -u APP_SERVICE --since "1 hour ago" --no-pager | tail -n 50

Если сбрасываются только большие загрузки, их отклоняет ограничение размера и закрывает соединение, пока браузер ещё отправляет данные. Tomcat читает не больше 2 МиБ отклонённой загрузки (maxSwallowSize); сверх этого, по его документации, клиент ответ вряд ли увидит. nginx с включённым по умолчанию lingering_close до 30 секунд дочитывает и выбрасывает остаток, так что браузер получает 413. Ставьте ограничение в nginx (client_max_body_size).

С Docker curl на хосте может показать сброс, если приложение в контейнере слушает только 127.0.0.1: docker-proxy принимает соединение, но передать его некуда. Сделайте так, чтобы приложение внутри контейнера слушало 0.0.0.0. Снаружи та же ошибка обычно выглядит как connection refused (англ.).

Причина 2: nginx сбрасывает соединения намеренно

return 444 закрывает соединение без ответа. По умолчанию это обычное закрытие, и браузер показывает ERR_EMPTY_RESPONSE. С reset_timedout_connection on nginx вместо этого отправляет RST — и для 444, и для запросов, упёршихся в client_body_timeout или send_timeout (по умолчанию 60 секунд без продвижения; простаивающие keep-alive-соединения по-прежнему закрываются обычным образом). Медленная загрузка или застрявшее скачивание на слабом мобильном канале тогда заканчиваются ERR_CONNECTION_RESET. Найдите эти директивы в загруженной конфигурации:

Debian · Ubuntu
sudo nginx -T 2>/dev/null | grep -nE 'return 444|reset_timedout_connection|lingering_close|client_max_body_size'

444 в общем default_server для неизвестных имён хостов — это нормально. А вот 444, на который попадают настоящие посетители, и есть ваш сброс. Никогда не ставьте lingering_close off: по документации nginx это нарушает протокол.

Причина 3: правила файрвола, fail2ban и ограничения частоты

Что увидит посетитель, зависит от того, когда срабатывает правило:

  • Отказ новым соединениям даёт refused, а не reset. ufw reject для TCP превращается в --reject-with tcp-reset, но ufw пропускает уже установленный трафик раньше ваших правил, так что ответ получает только первый пакет.
  • Стандартное действие fail2ban для iptables отклоняет с icmp-port-unreachable (действие для nftables — с reject), а его цепочка стоит в начале INPUT, поэтому бан задевает и открытые соединения: страница зависает, новые соединения получают отказ. Сброс появляется, только если кто-то задал blocktype как REJECT --reject-with tcp-reset.
  • Правила, которые срабатывают на открытых соединениях, и есть настоящий источник: ограничения числа соединений или частоты, записанные с --reject-with tcp-reset, IPS или WAF перед сервером, DDoS-фильтр выше по цепочке. limit_req и limit_conn в nginx отвечают HTTP-статусом (по умолчанию 503), а не сбросом.
Debian · Ubuntu · проверки только на чтение, затем снятие бана
# забанен ли посетитель и в каком jail?
sudo fail2ban-client banned VISITOR_IP

# правила, которые отправляют сбросы
sudo iptables -S | grep -i reset
sudo nft list ruleset | grep -iE 'reset|reject'

# снять бан
sudo fail2ban-client unban VISITOR_IP

Посетитель может узнать свой адрес на нашей странице What is my IP (англ.).

Причина 4: ядру не хватает памяти для сокетов

Под большой нагрузкой ядро сбрасывает соединения, которые больше не может себе позволить: осиротевшие сокеты сверх tcp_max_orphans или память TCP выше tcp_mem. Оно пишет об этом в лог, а его счётчики показывают, какой вид сбросов растёт:

Debian · Ubuntu
sudo dmesg -T | grep -E 'TCP: (too many orphaned sockets|out of memory)'

# запустите дважды с интервалом в минуту: второй запуск покажет только изменения
nstat TcpOutRsts TcpExtTCPAbortOnClose TcpExtTCPAbortOnData TcpExtTCPAbortOnMemory TcpExtListenOverflows
  • TcpExtTCPAbortOnClose: приложение закрыло сокет с непрочитанными данными, причина 1.
  • TcpExtTCPAbortOnData: намеренный сброс с SO_LINGER 0, например 444 в nginx с reset_timedout_connection.
  • TcpExtTCPAbortOnMemory: эта причина. Прежде чем поднимать лимиты, найдите, кто держит столько соединений.
  • TcpOutRsts учитывает и ответы сканерам на закрытых портах, поэтому растёт всегда. TcpExtListenOverflows (переполнена очередь accept) отбрасывает соединения, а не сбрасывает их, если только net.ipv4.tcp_abort_on_overflow не равен 1; по умолчанию он равен 0.

Причина 5: сбросы во время TLS-рукопожатия

Реальный вывод curl, сокращённый, от сервера, который сбрасывает соединение, как только приходит ClientHello:

Пример вывода · curl -sSv -o /dev/null https://…
* Connected to 127.0.0.1 (127.0.0.1) port 47101 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* Recv failure: Connection reset by peer
* OpenSSL SSL_connect: Connection reset by peer in connection to 127.0.0.1:47101
curl: (35) Recv failure: Connection reset by peer

nginx и Apache отвечают на проблемы с TLS сообщением alert, которое браузеры показывают как ERR_SSL_PROTOCOL_ERROR или похожий код, а не сбросом. Сброс здесь приходит от чего-то другого на этом порту (TCP-балансировщика, проброса порта, VPN, который делит порт 443) или от устройства, которое читает ClientHello: SNI-фильтра, файрвола с проверкой TLS или такого, который не справляется с большим постквантовым ClientHello. curl в Debian 12 (OpenSSL 3.0) отправляет маленький ClientHello и может пройти там, где Chrome получает сброс; OpenSSL 3.5 в Debian 13 по умолчанию предлагает key share X25519MLKEM768, так что сравните оба варианта:

Debian 13 · OpenSSL 3.5
openssl s_client -connect example.com:443 -servername example.com -groups X25519MLKEM768 -brief </dev/null
openssl s_client -connect example.com:443 -servername example.com -groups X25519 -brief </dev/null

Если первая команда получает сброс, а вторая подключается, устройство на пути не справляется с большими ClientHello. Обновите или замените его; никакая настройка веб-сервера это не исправит.

Причина 6: MTU и MSS в туннелях

За туннелем, например когда VPS пробрасывает порты на домашний сервер через WireGuard, полные пакеты по 1500 байт больше не помещаются. Если ICMP-сообщения «fragmentation needed» фильтруются, большие пакеты пропадают: соединение открывается, маленькие запросы работают, а на первом полноразмерном пакете всё зависает и заканчивается таймаутом или, если какое-то устройство сдаётся, сбросом. Если nginx на VPS проксирует запросы на домашний сервер, ядро уже подбирает размер таких соединений под туннель. Трафику, который VPS пересылает (DNAT), нужен MSS clamping: он переписывает размер сегмента в рукопожатии так, чтобы тот помещался:

iptables · например, в PostUp туннеля
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
nftables · внутри цепочки forward
tcp flags syn tcp option maxseg size set rt mtu

Сайт за Cloudflare

С оранжевым облаком TCP-соединение браузера заканчивается на Cloudflare, и всё, что делает ваш исходный сервер, приходит как страница ошибки Cloudflare: сброс после подключения становится ошибкой 520, отказ в соединении — 521 (англ.), отсутствие ответа — 522. Поэтому ERR_CONNECTION_RESET на проксируемом имени возникает между посетителем и Cloudflare: в его сети, в его антивирусе или в фильтре, который блокирует адреса Cloudflare или это имя хоста. Проверьте, что запись действительно проксируется: dig +short example.com должен вернуть адреса Cloudflare (AS13335).

Наш ASN Lookup (англ.) покажет, какой сети принадлежит адрес.

Если команда вернула IP вашего сервера, запись в режиме DNS only, и действуют причины 1–6. На VPS VMHeaven в Амстердаме или во Франкфурте у вас есть root для tcpdump, nstat и файрвола, а VNC-консоль в личном кабинете остаётся доступной, даже если правило файрвола закрыло вам SSH.

Частые вопросы

Что значит «Соединение сброшено» (ERR_CONNECTION_RESET)?

Браузер уже открыл соединение с сайтом, а затем получил пакет TCP reset, который его оборвал. Прислать такой пакет может сам сервер, файрвол перед ним или что-то по дороге: фильтр провайдера, антивирус с проверкой HTTPS, VPN или прокси. Это не ошибка самой страницы, поэтому очистка кеша и cookie помогает редко.

ERR_CONNECTION_RESET в Яндекс Браузере или на телефоне: что делать?

Причины те же, что в Chrome: Яндекс Браузер построен на Chromium и показывает тот же код. Откройте сайт в режиме инкогнито, отключите VPN и прокси (в Яндекс Браузере: Настройки → Системные → Сеть → Настройки прокси-сервера), приостановите веб-защиту антивируса. На телефоне переключитесь между Wi-Fi и мобильным интернетом и отключите VPN-приложение. Если сайт не открывается нигде, проблема на его стороне.

Чем ERR_CONNECTION_RESET отличается от ERR_CONNECTION_REFUSED?

Они случаются в разные моменты. Refused (в русском Chrome «не позволяет установить соединение») — ответ на самый первый пакет: порт никто не слушает или файрвол отклоняет. Reset (в русском Chrome «Соединение сброшено») значит, что соединение уже было открыто, часто запрос даже ушёл, когда сервер или устройство посередине оборвало его сбросом.

Читайте также

Все статьи раздела