Node.js LinuxWindowsNode.js

Node.js: В логах Node.js появляется EMFILE при большом количестве файлов

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

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

Ошибка EMFILE: too many open files означает, что процесс достиг ограничения открытых файловых дескрипторов. В Node.js она часто появляется при слишком большом числе одновременных fs-операций, незакрытых потоков или сокетов.

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

#Симптомы и условия возникновения

Ошибка EMFILE: too many open files означает, что процесс достиг ограничения открытых файловых дескрипторов. В Node.js она часто появляется при слишком большом числе одновременных fs-операций, незакрытых потоков или сокетов. Для начала проверьте используемую версию среды и точный текст ошибки на копии проекта, не меняя рабочий сервер.

#Причины и как их отличить

Возможная причинаКак узнатьЧто делать
Тысячи одновременных операцийВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.После Promise.all с чтением каталога ошибка воспроизводится сразуОграничить параллельные задачи.
Не закрываются файловые потокиВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.Число fd растёт после каждого заданияОбеспечить close/destroy и обработку error.
Низкий лимит службыВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.В интерактивной оболочке работает, под systemd нетСверить LimitNOFILE службы, менять только обоснованно.

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

  1. 1. Найдите точный стек EMFILEОткройте лог приложения и выпишите путь файла и вызов fs.open/readFile/createReadStream. Код ENFILE относится к общесистемному лимиту, а EMFILE — к процессу; смешивать их не следует.
  1. 2. Проверьте фактическое число дескрипторовВ Linux в отдельном терминале от владельца службы получите PID и посмотрите число элементов /proc/PID/fd. Если доступ запрещён, попросите администратора выполнить диагностику. Не закрывайте чужие fd вручную.
  2. Linux: замените PID на существующий идентификатор процесса
    Linux · Терминал (Bash)Команда
    Linux: замените PID на существующий идентификатор процесса. Число растёт при утечке или высокой параллельности.
    ls /proc/PID/fd | wc -l
  1. 3. Сверьте лимит процесса с systemdПроверьте /proc/PID/limits или systemctl show имя.service -p LimitNOFILE; это только чтение. Если у разных запусков лимиты отличаются, служба может иметь меньший предел.
  2. Linux, замените PID
    Linux · Терминал (Bash)Команда
    Linux, замените PID. Найдите строку Max open files.
    cat /proc/PID/limits
  1. 4. Ограничьте количество одновременных чтенийНайдите Promise.all(files.map(...)) на тысячи файлов. В тестовой копии замените безлимитный запуск на очередь с небольшим количеством работников (например, 8), увеличивайте значение по результатам замеров.
  1. 5. Корректно закрывайте ресурсыДля fs.promises.open поместите fileHandle.close() в finally; при работе с потоками добавьте обработчики error/close и дождитесь завершения. Если утечка в библиотеке, проверьте исправления производителя, не редактируйте файлы в node_modules вручную.
  1. 6. Повторите наблюдение после исправленияЗапустите одинаковый набор файлов на тестовой копии. Число fd во время работы должно ограниченно колебаться и возвращаться к базовому значению после окончания.
  1. 7. Изменяйте лимит только как последнюю меруЕсли расчёт параллельности показывает обоснованную потребность, администратор может настроить LimitNOFILE для конкретной службы и перезапустить в окно обслуживания. Увеличение лимита не устраняет утечку.
  2. Пример кода по теме
    Текст
    Безопасный пример закрытия файлового дескриптора в тестовом каталоге: заранее создайте небольшой test.txt. Для файла .mjs.
    import { open } from 'node:fs/promises';
    const handle = await open('./test.txt', 'r');
    try {
      const content = await handle.readFile({ encoding: 'utf8' });
      console.log(content.length);
    } finally {
      await handle.close();
    }

#Как проверить результат и что делать, если не помогло

Повторяемая партия файлов обрабатывается без EMFILE, а количество дескрипторов не растёт от запуска к запуску.

Если неисправность повторилась, выпишите первый код ошибки и действие, на котором она возвращается. Сравните версию Node.js/npm, рабочий каталог, настройки процесса и журнал тестового запуска. Откатите только внесённые изменения из предварительно сохранённой копии, затем разберите причину на отдельной среде.

Так эту ошибку тоже называют

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

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