Connection reset by peer в журнале службы
Сообщение Connection reset by peer (номер 104, ECONNRESET) означает, что другая сторона оборвала соединение. Единичные случаи нормальны, поток таких сообщений указывает на проблему: перезапуски, таймауты промежуточных устройств или несовпадение настроек.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Другая сторона перезапускалась
Перезапуск сервера обрывает все соединения. Клиенты видят сброс, и это ожидаемо.
-
Промежуточное устройство рвёт долгие соединения
Балансировщики и брандмауэры закрывают соединения после простоя. Приложение считает их живыми и получает сброс при следующей попытке.
-
Несовпадение настроек таймаутов
Клиент держит соединение дольше, чем позволяет сервер. Сервер закрывает, клиент видит сброс при следующем запросе.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Частота сбросов: единичные случаи и поток — разные ситуации.
journalctl -u myapp.service --since "1 hour ago" --no-pager | grep -ci resetЧисло установленных соединений.
ss -tan state established | wc -lРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Перезапуск сервера обрывает все соединения. Клиенты видят сброс, и это ожидаемо.
- Как проверить
-
Сопоставьте время сообщений и перезапусков.
journalctl -u myapp.service -n 30 --no-pager | grep -i reset journalctl -u зависимость.service --no-pager | grep -iE "started|stopped" | tail -5
- Как исправить
- Ничего исправлять не нужно, если перезапуск был плановым. Приложение должно переподключаться само — это проверяется именно в такой ситуации.
- Почему происходит
- Балансировщики и брандмауэры закрывают соединения после простоя. Приложение считает их живыми и получает сброс при следующей попытке.
- Как проверить
-
Посмотрите частоту сбросов и периодичность.
journalctl -u myapp.service --since "1 hour ago" --no-pager | grep -c -i reset
- Как исправить
- Включите проверочные пакеты на уровне соединения или сократите время жизни соединений в пуле до значения меньше таймаута устройства.
- Почему происходит
- Клиент держит соединение дольше, чем позволяет сервер. Сервер закрывает, клиент видит сброс при следующем запросе.
- Как проверить
-
Сравните таймауты обеих сторон.
sudo nginx -T 2>/dev/null | grep -i keepalive_timeout journalctl -u myapp.service -n 20 --no-pager | grep -i reset
- Как исправить
- Сделайте таймаут клиента меньше серверного: тогда соединение будет закрываться предсказуемо, со стороны клиента.
Пример вывода
Промежуточное устройство оборвало простаивающее соединение. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[1200]: error: read tcp <адрес>:54321-><адрес>:5432: read: connection reset by peer
myapp[1200]: info: reconnecting to database (attempt 1)
Связанные ошибки
- Connection timed out в журнале службы Соединение не устанавливается по таймауту: пакеты отбрасываются, узел недоступен, перегружен сервер на другой стороне.
- Broken pipe в журнале службы Запись в закрытый канал или соединение: клиент отключился, обработчик завершился, конвейер разорван.
- Connection refused в журнале службы Соединение отклонено: служба не может подключиться к базе, кешу или другому сервису. Порядок запуска, адрес, брандмауэр.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Automount: каталог монтируется не вовремя или отваливается Автомонтирование через .automount: как работает TimeoutIdleSec, почему ресурс отваливается и когда лучше обычный .mount.
- Cannot assign requested address при привязке Ошибка 99 при привязке: адрес не принадлежит машине или ещё не поднят. Разбор с network-online.target и ip_nonlocal_bind.
- Docker: имена не разрешаются внутри контейнера Контейнеры не разрешают имена: конфликт с локальным разрешателем, неверные серверы в daemon.json, отключённый проброс.
- Docker: правила брандмауэра конфликтуют с вашими После перезапуска брандмауэра контейнеры теряют сеть: Docker управляет своими правилами сам.
Где встречается чаще всего
Источники
- recv(2): ошибка ECONNRESET
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено перезапуском базы при открытых соединениях приложения.