ERR_NETWORK_CHANGED: почему Chrome пишет «Соединение прервано» и что с этим делать владельцу сайта
Страница оборвалась: «Соединение прервано. Похоже, вы подключились к другой сети», внизу мелко — ERR_NETWORK_CHANGED. Через секунду обновилась сама, потом повторилось. Разбираем, что Chrome считает «сменой сети», где искать причину на Windows, macOS, Linux, Android и iOS — и когда жалобы пользователей всё-таки указывают на сайт, а не на их Wi-Fi.
ERR_NETWORK_CHANGED (код -21 в Chromium) — ошибка, которую Chrome показывает, когда во время запроса изменилась сеть на устройстве пользователя: сменился IP-адрес, активный сетевой интерфейс или маршрут по умолчанию. Браузер сбрасывает все открытые соединения и незавершённые DNS-запросы, и текущая загрузка обрывается. Это событие на стороне клиента: сервер сайта о нём не узнаёт и повлиять на него не может — но может сделать его заметнее.
Что происходит внутри Chrome при смене сети
За это отвечает компонент NetworkChangeNotifier: он слушает события ОС (уведомления об адресах в Windows, netlink в Linux, системный конфигуратор в macOS и iOS, ConnectivityManager в Android) и рассылает сигнал «IP-адрес основного интерфейса изменился». По исходному коду Chromium дальше происходит цепочка сбросов — она в таблице.
| Компонент Chrome | Что делает при смене IP | Что видит пользователь |
|---|---|---|
| Пул TCP-сокетов | Закрывает все соединения и незавершённые подключения | Незагруженные страницы и ресурсы получают -21 |
| DNS-резолвер | Сбрасывает кеш, прерывает текущие запросы, заново проверяет IPv6 | Первая загрузка после переключения чуть дольше |
| QUIC (HTTP/3) | Закрывает сессии с QUIC_IP_ADDRESS_CHANGED, забывает, что QUIC здесь работал | Сайт на HTTP/3 первое время ходит по TCP |
| Страница ошибки | Автоматически перезагружается через 1 с, 5 с, 30 с, 1, 5, 10 и 30 минут | «Само прошло» через секунду-две |
Автоперезагрузка объясняет, почему ошибка мелькает и исчезает: Chrome повторяет попытку для основного документа, если вкладка видима и сеть есть. Для картинок, скриптов и XHR повторов нет — они остаются битыми до ручного обновления. Деталь из исходников на сентябрь 2026: ротация временных IPv6-адресов (RFC 8981, по умолчанию раз в сутки) больше не считается сменой сети — раньше это была частая причина ложных срабатываний.
Где живёт причина: от адаптера до сайта
Почти всегда причина — на устройстве или между ним и роутером, потому что триггер локальный: смена адреса или интерфейса. Сайт не может «отправить» пользователю ERR_NETWORK_CHANGED, но может держать соединение открытым так долго, что любая смена сети в него попадёт.
| Уровень | Как часто | Типичный сценарий | Как проверить |
|---|---|---|---|
| Адаптер устройства | Чаще всего | Телефон перескочил с Wi-Fi на LTE; ноутбук проснулся; Windows отключила адаптер «для экономии энергии»; роуминг между точками | Ошибка только на этом устройстве; журнал ОС показывает переподключения |
| VPN, прокси, антивирус | Часто | VPN-клиент переподключается или меняет сервер; «веб-защита» антивируса перезапускает свой фильтр | Отключить VPN и веб-защиту на 15 минут — ошибка пропала или нет |
| Виртуальные адаптеры | Часто у разработчиков | VirtualBox, VMware, Hyper-V (vEthernet), WSL2, Docker Desktop поднимают и опускают интерфейсы при старте ВМ или контейнера | Отключить лишние адаптеры в диспетчере устройств; сопоставить ошибки со стартом контейнеров |
| Роутер | Иногда | Короткая аренда DHCP, band steering между 2,4 и 5 ГГц под одним SSID, mesh-роуминг, кривые IPv6 Router Advertisement | Ошибка на всех устройствах; срок аренды в ipconfig /all; логи роутера |
| Провайдер | Редко | Обрыв PPPoE-сессии и смена внешнего адреса; переключение в CGNAT | Счётчик переподключений WAN в роутере; совпадение по времени на всех устройствах |
| Сайт | Напрямую — никогда | Не вызывает смену сети, но делает её заметной: долгие запросы, файлы без докачки, битый IPv6 | Раздел для владельца ниже |
Как исправить ERR_NETWORK_CHANGED на Windows, macOS, Linux, Android и iOS
Порядок один для всех систем: убрать то, что дёргает сеть (VPN, виртуальные адаптеры, энергосбережение), затем сбросить DNS и сетевой стек, и только потом трогать роутер. Первый шаг — открыть сайт с другого устройства в той же сети: если там всё в порядке, роутер и провайдер ни при чём.
| ОС | Первым делом | Если не помогло |
|---|---|---|
| Windows 10/11 | Диспетчер устройств → адаптер → «Управление электропитанием» → снять «Разрешить отключение для экономии энергии». Отключить лишние адаптеры VirtualBox, Hyper-V, vEthernet | Сброс DNS, Winsock и TCP/IP (ниже), перезагрузка, драйвер Wi-Fi с сайта производителя ноутбука |
| macOS | Отключить VPN и «фильтры контента» сторонних антивирусов. В настройках Wi-Fi убрать автоподключение к нестабильным сетям | Сброс DNS-кеша (ниже), удалить и заново добавить Wi-Fi в Системных настройках → Сеть |
| Linux | Журнал NetworkManager: кто и как часто переподключает интерфейс. Отключить лишние профили соединений | resolvectl flush-caches, перезапуск NetworkManager, проверить интерфейсы docker и libvirt |
| Android | Настройки → Сеть и интернет → Частный DNS: если указан DoT-сервер и он недоступен, Android помечает сеть как «без интернета» и уходит на мобильную. Переключить на «Автоматически» | Выключить «переход на мобильную сеть при плохом Wi-Fi» (название зависит от производителя), отключить VPN-приложения, сбросить настройки сети |
| iOS / iPadOS | Настройки → Сотовая связь → выключить «Помощь Wi-Fi»: она переводит трафик на LTE, когда Wi-Fi слабеет | Отключить VPN-профили и Private Relay для проверки, «Забыть эту сеть», сброс настроек сети |
Windows, командная строка от администратора. По документации Microsoft сбросу TCP/IP нужен лог-файл, а после команды — перезагрузка:
ipconfig /flushdns ipconfig /release && ipconfig /renew netsh winsock reset netsh int ip reset resetlog.txt # затем перезагрузка обязательна netsh wlan show interfaces # SSID, канал, уровень сигнала netsh interface ipv6 show addresses # временные адреса помечены Temporary
macOS. По заметке Apple для версий от 10.10.4 кеш сбрасывает killall -HUP mDNSResponder; dscacheutil -flushcache остался от 10.6 и вреда не приносит:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder networksetup -listallnetworkservices # какие сервисы активны networksetup -getdnsservers Wi-Fi # чей DNS используется scutil --dns | head -20 # реальные резолверы ifconfig | grep -E 'inet6.*temporary' # временные IPv6-адреса
Linux с systemd-resolved и NetworkManager. Главное здесь журнал: в нём видно, кто переключает интерфейс.
resolvectl flush-caches resolvectl status | head -20 nmcli device status nmcli connection show --active journalctl -u NetworkManager -f # смотреть в момент ошибки sysctl net.ipv6.conf.all.use_tempaddr # 2 = временные IPv6 предпочитаются
В самом Chrome: chrome://net-internals/#dns — кнопка «Clear host cache», chrome://net-internals/#sockets — «Flush socket pools»; они снимают последствия, не причину. Причину показывает лог: открыть chrome://net-export, нажать «Start Logging to Disk», воспроизвести ошибку в другой вкладке, остановить и открыть файл в netlog-viewer. Искать события NETWORK_IP_ADDRESSES_CHANGED и NETWORK_CHANGED.
Совет из старых форумов помогал, когда Chrome реагировал на ротацию временных адресов; в актуальных сборках эта причина закрыта. Отключение IPv6 маскирует симптом и не лечит ни энергосбережение адаптера, ни VPN. Сначала лог, потом решение.
Когда жалобы на ERR_NETWORK_CHANGED указывают на проблему сайта
Смена сети длится секунды, и запрос, который укладывается в сотни миллисекунд, в неё почти не попадает. Если жалуются именно на ваш сайт, значит, ваши запросы живут дольше, чем у соседей: тяжёлая страница на мобильном, загрузка файла на десятки секунд, долгий POST, WebSocket. Второй сценарий — битый IPv6: AAAA ведёт на адрес, который не отвечает, и клиенты теряют секунды на переборе адресов при каждом переподключении.
| Что проверить | Почему это связано с ошибкой | Норма |
|---|---|---|
| AAAA-запись и живой IPv6 | Клиенты предпочитают IPv6 (RFC 8305, Happy Eyeballs v2). Если адрес из AAAA не отвечает, каждое подключение начинается с неудачной попытки | Либо AAAA нет, либо curl -6 отдаёт 200 не медленнее curl -4 |
| Вес главной страницы на мобильном | Чем дольше грузится документ, тем выше шанс поймать переключение Wi-Fi/LTE | HTML-документ отдаётся за доли секунды, критичный контент — в первых ответах |
| Range и валидаторы у больших файлов | По коду Chromium докачка возможна только при Accept-Ranges: bytes и ETag или Last-Modified; иначе после обрыва файл качается с нуля | Запрос с Range возвращает 206 и Content-Range |
| Keep-alive и HTTP/2 | Меньше новых TCP-подключений — меньше окон, в которые попадёт смена сети | curl показывает HTTP/2 (или HTTP/3), соединения не закрываются после каждого ответа |
| Долгие запросы: экспорт, отчёт, загрузка | POST на 40 секунд обрывается вместе с сетью, повторить его Chrome не предложит | Долгие операции идут в фоне, страница опрашивает статус короткими запросами |
Проверка с любого ноутбука, вывод — пример для условного домена:
# Есть ли AAAA и отвечает ли адрес по IPv6
dig AAAA example.ru +short
2001:db8::1234
curl -6 -sS -o /dev/null -w 'IPv6: %{http_code} %{time_total}s\n' https://example.ru/
curl -4 -sS -o /dev/null -w 'IPv4: %{http_code} %{time_total}s\n' https://example.ru/
IPv6: 000 20.012s # таймаут — AAAA ведёт в никуда
IPv4: 200 0.381s
# Вес документа и версия протокола
curl -sS -o /dev/null -w '%{size_download} байт, %{http_version}, %{time_total}s\n' https://example.ru/
412873 байт, 2, 0.902s
# Докачка: заголовки и пробный Range-запрос
curl -sI https://example.ru/files/catalog.pdf | grep -iE 'accept-ranges|content-length|etag|last-modified'
accept-ranges: bytes
content-length: 58712344
etag: "66f1a3c2-37fe618"
curl -sS -r 0-1023 -o /dev/null -w '%{http_code}\n' https://example.ru/files/catalog.pdf
206
Если curl -6 висит до таймаута, а curl -4 отвечает мгновенно — удалите AAAA или почините IPv6 на сервере: RFC 8305 отводит на переключение между семействами адресов 250 мс, но это работает, только когда IPv6-адрес быстро отказывает, а не молча теряет пакеты. Если Range-запрос вернул 200 вместо 206 — каждая смена сети означает загрузку файла заново.
Как отличить массовую проблему от единичной
Массовая проблема видна из любой сети одновременно, единичная — у одного пользователя. Поэтому первое действие при жалобе — открыть сайт из другой сети: с телефона через LTE, с сервера через curl, из другого региона через внешние точки мониторинга. Если оттуда сайт отдаёт 200 за обычное время, причина у клиента, и дальше работает чек-лист по ОС.
Второе — сверить DNS: проверка DNS-записей покажет, что отдают A и AAAA прямо сейчас, и поймает момент, когда в зоне появилась AAAA на адрес, который не слушает 443-й порт. Третье — попросить у пользователя NetLog: одного файла достаточно, чтобы увидеть, менялся ли у него IP-адрес в момент ошибки.
Пруфен проверяет доступность и время ответа сайта с интервалом от 2 минут из 13 точек мониторинга — 11 в России, а также Минск и Испания. Пришла жалоба на ERR_NETWORK_CHANGED — откройте историю по локациям: если все точки в это время получали ответ, сайт был доступен, искать нужно в сети пользователя. Если ответ пропал в нескольких точках сразу, вы узнаете об этом раньше жалобы — уведомлением в Email, Telegram или Макс, а если ресурс так и не поднялся, подключается голосовой звонок.
Соседние ошибки Chrome и чем они отличаются
У соседних ошибок сетевого уровня свой триггер и своя сторона: по коду сразу видно, стоит ли вообще смотреть на сервер.
| Код | Что случилось по данным Chromium | Чья сторона |
|---|---|---|
| ERR_NETWORK_CHANGED (-21) | Сеть изменилась во время запроса, соединения сброшены | Клиент |
| ERR_INTERNET_DISCONNECTED (-106) | Интернет-соединение потеряно; на экране «Нет подключения к интернету» | Клиент |
| ERR_ADDRESS_UNREACHABLE (-109) | Нет маршрута до адреса — типично для битого IPv6 или VPN с неполной таблицей маршрутов | Клиент или маршрут; иногда AAAA сайта |
| ERR_CONNECTION_RESET (-101) | Пришёл TCP RST: соединение оборвала другая сторона или устройство между ними | Сервер, файрвол, DPI |
| DNS_PROBE_FINISHED_NO_INTERNET | DNS не ответил, и проверочный запрос Chrome тоже не прошёл — сети нет | Клиент |
| ERR_NAME_NOT_RESOLVED (-105) | Имя хоста не разрешилось; сеть при этом есть | DNS сайта или резолвер клиента |
Правило: -21, -106 и DNS_PROBE_FINISHED_NO_INTERNET сервер не увидит никогда; -101 и -105 требуют проверки со своей стороны; при -109 первым делом смотрите на свою AAAA-запись. Общий порядок разбора — в статье сайт не работает: как понять, у кого проблема.
Частые вопросы
Почему ошибка появляется только на одном сайте, если проблема в моей сети?
Потому что в момент смены сети именно этот сайт что-то грузил. Обрываются только запросы в полёте: сайт с открытым WebSocket, долгим POST или тяжёлой страницей попадает в окно чаще, чем давно загруженная страница. В NetLog видно и событие смены адреса, и запросы, которые оно закрыло.
Может ли ERR_NETWORK_CHANGED появляться на сервере, например в headless Chrome или Puppeteer?
Да, по той же причине: headless Chrome использует тот же NetworkChangeNotifier. На хосте с Docker или Kubernetes виртуальные интерфейсы поднимаются и опускаются при каждом старте контейнера, и парсер получает -21 посреди работы. Лечится запуском браузера в изолированном сетевом пространстве либо повтором запроса в скрипте.
Загрузка файла оборвалась с этой ошибкой. Продолжится ли она с того же места?
Зависит от сервера. По коду Chromium сетевые обрывы, включая смену сети, переводят загрузку в состояние «нужно действие пользователя» — появится кнопка «Возобновить». Докачка с места обрыва произойдёт, только если в ответе были Accept-Ranges: bytes и ETag или Last-Modified; без них Chrome начнёт файл заново. Проверка: curl -r 0-1023 должен вернуть 206.
Пользователь на VPN жалуется на ошибку каждые несколько минут. Что ему посоветовать?
Проверить, не переподключается ли VPN-клиент: автовыбор сервера и «переподключение при ухудшении сети» меняют IP-адрес туннеля при каждом цикле. Помогает закрепить один сервер и обновить клиент. Если при выключенном VPN ошибка исчезает, вопрос к VPN-провайдеру, а не к сайту.