Node.js WindowsLinuxmacOS

Как исправить ECONNRESET при отправке большого тела HTTP-запроса из Node.js

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

ECONNRESET означает, что TCP-соединение было неожиданно закрыто. При большом POST это может происходить из-за ограничения размера запроса на сервере или прокси, тайм-аута, закрытия сокета приложением либо обрыва сети. Сам размер запроса ещё не доказывает причину; сначала сравните маленький и большой запрос и журналы обеих сторон.

В этой статье
  1. Что означает ошибка и когда она возникает
  2. Как отличить возможные причины
  3. Пошаговая диагностика и устранение
  4. Минимальный пример и проверка на тестовом проекте
  5. Проверка результата и действия при неуспехе

#Что означает ошибка и когда она возникает

ECONNRESET означает, что TCP-соединение было неожиданно закрыто. При большом POST это может происходить из-за ограничения размера запроса на сервере или прокси, тайм-аута, закрытия сокета приложением либо обрыва сети. Сам размер запроса ещё не доказывает причину; сначала сравните маленький и большой запрос и журналы обеих сторон.

#Как отличить возможные причины

Возможная причинаКак узнатьЧто делать
Ограничение тела в приложении или проксиСервер или обратный прокси ограничивает размер принимаемого тела; корректный ответ часто 413, но некоторые конфигурации разрывают соединение.Малый POST работает, большой — нет; в журнале 413 или текст о превышении body limit.Согласовать нужный предел и корректную обработку 413 на сервере.
Время передачи превышает лимитМедленная загрузка и серверный тайм-аут приводят к закрытию соединения во время передачи.Ошибка возникает на медленном канале; размер меньше установленного лимита.Сопоставить тайминги и параметры отдельных участков цепочки.
Приложение прерывает соединениеСервер вызывает destroy() или падает при разборе тела; клиент получает socket hang up / ECONNRESET.В журнале сервера есть необработанное исключение, закрытие сокета или рестарт контейнера.Исправить обработчик, вместо резкого закрытия отдавать понятный статус.

#Пошаговая диагностика и устранение

  1. Сохраните минимальные параметры сбойного запросаНа тестовом клиенте запишите адрес без ключей и секретов, метод POST/PUT, Content-Type, объём тела в байтах, время до ошибки и наличие кода HTTP. Не копируйте реальное содержимое загружаемых файлов в технический отчёт. Если получен HTTP 413, это явный ответ сервера; если ECONNRESET, ответа могло не быть.
  2. Проверьте, что ошибка относится к большому телуИз той же сети отправьте безопасный небольшой тестовый файл тем же способом в контролируемую конечную точку, затем файл чуть больше. Если сбой происходит только выше определённого порога, подозревайте лимит; если случайно при любом размере — ищите сеть, тайм-аут и нагрузку.
  3. Проверьте клиентский обработчик ошибок и времяВ коде Node.js найдите http.request/https.request/fetch и место, где передаётся тело. Для http.request добавьте обработчик req.on("error", ...) и фиксируйте error.code, размер, время, но не токены. ECONNRESET обычно сопровождается socket hang up при преждевременном закрытии соединения до получения ответа.
  4. Изучите журнал сервера и обратного проксиЕсли это ваш сервис, откройте журнал приложения и прокси в тот же момент времени; проверьте сообщения о превышении размера тела, 413, 408, timeout и перезапуске процесса. На чужом API попросите провайдера сообщить разрешённый размер и варианты загрузки частями; не повышайте клиентские лимиты вслепую.
  5. Проведите безопасный локальный экспериментСоздайте в пустой папке файлы local-server.cjs и local-client.cjs из примеров. В первом терминале выполните node local-server.cjs; во втором — node local-client.cjs. Сервер специально закрывает сокет после превышения небольшого лимита — клиент печатает ECONNRESET без обращения в интернет.
  6. Исправьте серверный лимит там, где он действительно нуженЕсли доказано, что ваше приложение ограничивает тело раньше допустимого размера, задайте документированный лимит ровно для нужного маршрута, с учётом защиты от слишком больших загрузок. Для Express это может быть параметр limit у соответствующего обработчика тела, для Nginx — client_max_body_size; на сервере сначала резервная копия и проверка конфигурации, затем осторожная перезагрузка. Не меняйте ограничения глобально без расчёта ресурсов.
  7. Обеспечьте корректный ответ вместо аварийного разрываПри превышении допустимого размера сервер должен возвращать понятный статус, например 413, и корректно завершать работу с запросом, а не внезапно уничтожать соединение. Если используется загрузка больших файлов, изучите потоковую передачу и ограничения временного хранилища, а не сохраняйте произвольный размер целиком в память.
  8. Проверьте восстановление и возврат настроекПосле изменения повторите тест двух размеров: допустимый проходит с ожидаемым HTTP-кодом, недопустимый получает предсказуемый отказ, а не случайный ECONNRESET. Если соединение всё ещё обрывается, соберите временные метки клиента, прокси и приложения; при ухудшении загрузки восстановите прежние настройки из резервной копии.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Выполнить в локальной учебной папке, первый терминал.
    Linux · Терминал (Bash)Команда
    Выполнить в локальной учебной папке, первый терминал. Сервер слушает только 127.0.0.1:31056; если порт занят, выберите другой свободный и измените его в обоих примерах.
    node --version
    node local-server.cjs
    Вариант 2Во втором терминале той же папки.
    Linux · Терминал (Bash)Команда
    Во втором терминале той же папки. Данные искусственные, сеть не покидает компьютер.
    node local-client.cjs

#Минимальный пример и проверка на тестовом проекте

Текст
Сохранить как local-server.cjs. Разрыв socket здесь намеренно имитирует неверную реализацию; НЕ копируйте такой обработчик в реальный сервер.
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("Ожидаю запрос"));
Текст
Сохранить как local-client.cjs. В учебной схеме обычно увидите ECONNRESET. Если нет, проверьте верный порт и оба терминала.
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);

#Проверка результата и действия при неуспехе

На контролируемой точке малые и допустимые крупные запросы заканчиваются ожидаемым ответом, а превышение лимита даёт понятный статус. Если ошибка появляется только через прокси, проверяйте именно его логи и ограничения; если на прямом соединении — приложение/тайм-аут. Не повторяйте огромные запросы на чужие сервисы без разрешения.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.