#Что означает ошибка и когда она возникает
ECONNRESET означает, что TCP-соединение было неожиданно закрыто. При большом POST это может происходить из-за ограничения размера запроса на сервере или прокси, тайм-аута, закрытия сокета приложением либо обрыва сети. Сам размер запроса ещё не доказывает причину; сначала сравните маленький и большой запрос и журналы обеих сторон.
#Как отличить возможные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Ограничение тела в приложении или проксиСервер или обратный прокси ограничивает размер принимаемого тела; корректный ответ часто 413, но некоторые конфигурации разрывают соединение. | Малый POST работает, большой — нет; в журнале 413 или текст о превышении body limit. | Согласовать нужный предел и корректную обработку 413 на сервере. |
| Время передачи превышает лимитМедленная загрузка и серверный тайм-аут приводят к закрытию соединения во время передачи. | Ошибка возникает на медленном канале; размер меньше установленного лимита. | Сопоставить тайминги и параметры отдельных участков цепочки. |
| Приложение прерывает соединениеСервер вызывает destroy() или падает при разборе тела; клиент получает socket hang up / ECONNRESET. | В журнале сервера есть необработанное исключение, закрытие сокета или рестарт контейнера. | Исправить обработчик, вместо резкого закрытия отдавать понятный статус. |
#Пошаговая диагностика и устранение
- Сохраните минимальные параметры сбойного запросаНа тестовом клиенте запишите адрес без ключей и секретов, метод POST/PUT, Content-Type, объём тела в байтах, время до ошибки и наличие кода HTTP. Не копируйте реальное содержимое загружаемых файлов в технический отчёт. Если получен HTTP 413, это явный ответ сервера; если ECONNRESET, ответа могло не быть.
- Проверьте, что ошибка относится к большому телуИз той же сети отправьте безопасный небольшой тестовый файл тем же способом в контролируемую конечную точку, затем файл чуть больше. Если сбой происходит только выше определённого порога, подозревайте лимит; если случайно при любом размере — ищите сеть, тайм-аут и нагрузку.
- Проверьте клиентский обработчик ошибок и времяВ коде Node.js найдите
http.request/https.request/fetch и место, где передаётся тело. Для http.request добавьте обработчик req.on("error", ...) и фиксируйтеerror.code, размер, время, но не токены.ECONNRESETобычно сопровождаетсяsocket hang upпри преждевременном закрытии соединения до получения ответа. - Изучите журнал сервера и обратного проксиЕсли это ваш сервис, откройте журнал приложения и прокси в тот же момент времени; проверьте сообщения о превышении размера тела, 413, 408, timeout и перезапуске процесса. На чужом API попросите провайдера сообщить разрешённый размер и варианты загрузки частями; не повышайте клиентские лимиты вслепую.
- Проведите безопасный локальный экспериментСоздайте в пустой папке файлы local-server.cjs и local-client.cjs из примеров. В первом терминале выполните
node local-server.cjs; во втором —node local-client.cjs. Сервер специально закрывает сокет после превышения небольшого лимита — клиент печатаетECONNRESETбез обращения в интернет. - Исправьте серверный лимит там, где он действительно нуженЕсли доказано, что ваше приложение ограничивает тело раньше допустимого размера, задайте документированный лимит ровно для нужного маршрута, с учётом защиты от слишком больших загрузок. Для Express это может быть параметр limit у соответствующего обработчика тела, для Nginx — client_max_body_size; на сервере сначала резервная копия и проверка конфигурации, затем осторожная перезагрузка. Не меняйте ограничения глобально без расчёта ресурсов.
- Обеспечьте корректный ответ вместо аварийного разрываПри превышении допустимого размера сервер должен возвращать понятный статус, например 413, и корректно завершать работу с запросом, а не внезапно уничтожать соединение. Если используется загрузка больших файлов, изучите потоковую передачу и ограничения временного хранилища, а не сохраняйте произвольный размер целиком в память.
- Проверьте восстановление и возврат настроекПосле изменения повторите тест двух размеров: допустимый проходит с ожидаемым HTTP-кодом, недопустимый получает предсказуемый отказ, а не случайный ECONNRESET. Если соединение всё ещё обрывается, соберите временные метки клиента, прокси и приложения; при ухудшении загрузки восстановите прежние настройки из резервной копии.
- Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Минимальный пример и проверка на тестовом проекте
const http = require("node:http");
const server = http.createServer((req, res) => {
let bytes = 0;
req.on("data", chunk => {
bytes += chunk.length;
if (bytes > 1024) req.destroy(); // только учебная имитация ошибки
});
req.on("end", () => { res.writeHead(200); res.end("OK"); });
});
server.on("error", console.error);
server.listen(31056, "127.0.0.1", () => console.log("Ожидаю запрос"));const http = require("node:http");
const body = Buffer.alloc(2048, "x");
const req = http.request({hostname:"127.0.0.1",port:31056,path:"/",method:"POST",headers:{"Content-Length":body.length}}, res => {
console.log("HTTP", res.statusCode); res.resume();
});
req.on("error", err => console.error("Код ошибки:", err.code));
req.end(body);#Проверка результата и действия при неуспехе
На контролируемой точке малые и допустимые крупные запросы заканчиваются ожидаемым ответом, а превышение лимита даёт понятный статус. Если ошибка появляется только через прокси, проверяйте именно его логи и ограничения; если на прямом соединении — приложение/тайм-аут. Не повторяйте огромные запросы на чужие сервисы без разрешения.