EMFILE / ENFILE: too many open files (watchpack, chokidar, ulimit)

A bundler or Node process crashed with EMFILE / ENFILE — too many open files. The OS hit a per-process or system-wide file-descriptor limit, almost always during file watching or a huge parallel read.

What EMFILE and ENFILE mean

Error: EMFILE: too many open files (libuv / Node errno -24) means the process reached its nofile soft limit. ENFILE is rarer: the kernel’s global file table is full. Dev servers (webpack, Vite, Next, Metro, watchpack, chokidar) open a handle per watched file — monorepos blow past macOS’s historic 256/1024 defaults quickly.

Error: EMFILE: too many open files, watch
    at FSWatcher._handle.onchange (node:internal/fs/watchers:…)
# or from watchpack / chokidar during next dev / vite

Cause table

SymptomLikely causeFix
EMFILE on watch / chokidarFile watcher + low ulimit -nRaise nofile; narrow watch globs; exclude node_modules / .git
Only on macOSLow default soft limitulimit -n 10240; persist via launchctl limit maxfiles / shell profile
Only under systemd serviceDefault LimitNOFILE (often 1024)LimitNOFILE=65535 in the unit; systemctl daemon-reload
Only in Docker / K8sContainer nofile / pid limits--ulimit nofile=65535:65535; pod securityContext / container ulimits
ENFILESystem-wide table fullFind runaway processes (lsof); reboot last resort; raise fs.file-max
Linux: “OS file watch limit reached”inotify watches exhaustedRaise fs.inotify.max_user_watches (and often max_user_instances)

Raise the limit (quick → lasting)

# Current soft/hard limits
ulimit -n
ulimit -Hn

# This shell only
ulimit -n 10240

# Linux persistent (example): /etc/security/limits.conf
# *  soft  nofile  65535
# *  hard  nofile  65535

# systemd service snippet
# [Service]
# LimitNOFILE=65535

# Docker
docker run --ulimit nofile=65535:65535 …

On modern Linux, pam limits apply to login shells; services started by systemd ignore limits.conf unless LimitNOFILE is set. GUI/IDE terminals sometimes inherit a different limit than SSH.

Watchers: webpack, Vite, Next

Linux inotify

cat /proc/sys/fs/inotify/max_user_watches
# temporary
sudo sysctl -w fs.inotify.max_user_watches=524288
# persistent: fs.inotify.max_user_watches=524288 in /etc/sysctl.d/*.conf

inotify limits are separate from ulimit -n. You can have free file descriptors and still fail to add watches.

Who is holding files open?

lsof -p $(pgrep -n node) | wc -l
lsof +D /path/to/project 2>/dev/null | wc -l
# per-process count (Linux)
ls /proc/PID/fd | wc -l

A stuck previous node / IDE language server can leak descriptors across restarts — kill orphans before raising limits forever. Mystery errno strings? Paste into What is this?.

Related

JavaScript heap out of memory · Killed: exit code 137 · EADDRINUSE · ENOSPC no space left · npm ERR! code ELIFECYCLE

Questions

What is Error EMFILE: too many open files?

The process hit its open file-descriptor (nofile) limit. Dev file watchers and large parallel I/O are the usual triggers.

EMFILE vs ENFILE?

EMFILE is per-process. ENFILE is system-wide. Fix EMFILE with ulimit/LimitNOFILE; for ENFILE find runaway processes and consider fs.file-max.

Why does Vite / webpack / Next hit this?

They watch thousands of source files. macOS and systemd defaults are often too low for monorepos.

Is ulimit -n enough under systemd?

No. Set LimitNOFILE in the unit file; login-shell ulimit does not apply to most services.

What about inotify max_user_watches?

On Linux, watchers also need enough inotify watches — raise fs.inotify.max_user_watches separately from ulimit.

How do I see how many files a process has open?

lsof -p PID | wc -l, or ls /proc/PID/fd | wc -l on Linux.

Published .

Try it

Related guides

Newest guides