Linux / Bash

Linux "Too Many Open Files" Error Fix

The "too many open files" error means a process has hit the maximum number of file descriptors it's allowed to have open simultaneously — and while raising the limit is often part of the fix, the more important question is usually why so many files or connections are staying open in the first place.

The Problem

An application starts failing with errors like:

Too many open files
EMFILE: too many open files, open '/path/to/file'
accept4(): Too many open files

This often happens under load, or gradually over time as a long-running process accumulates open file descriptors it never releases.

Why It Happens

Every process on Linux has a limit on how many file descriptors (open files, sockets, pipes) it can have simultaneously, set both at the system level and per-user/per-process. The most common causes are:

  • The default limit (often 1024) is genuinely too low for a high-concurrency application like a web server handling many simultaneous connections
  • The application has a file descriptor leak — opening files, database connections, or sockets without properly closing them, so the count grows over time until it hits the ceiling
  • A specific code path (like an error handler) skips the normal cleanup/close logic when an exception occurs, leaking a handle every time that particular error happens

The Fix

First, check the current limit for your user and confirm it's actually the constraint being hit:

ulimit -n

If this shows a low number like 1024 and your application genuinely needs more (a busy web server, for example), raise it. For a temporary change in the current shell session:

ulimit -n 65536

For a permanent change that survives reboots and applies system-wide, edit the limits configuration:

# /etc/security/limits.conf
your_username soft nofile 65536
your_username hard nofile 65536

If the application runs as a systemd service, the limits.conf change alone often isn't enough, since systemd services don't always inherit these settings. Set the limit explicitly in the service's unit file instead:

# /etc/systemd/system/your-app.service
[Service]
LimitNOFILE=65536

After editing a systemd unit file, reload the daemon and restart the service for the change to take effect:

sudo systemctl daemon-reload
sudo systemctl restart your-app

Before assuming a higher limit is the whole fix, check whether the number of open files is actually growing unbounded, which points to a leak rather than a genuinely high but stable need. Monitor the count for a running process over time:

ls /proc/<pid>/fd | wc -l

If this number keeps climbing steadily during normal operation rather than stabilizing, raising the limit only delays the eventual failure — the real fix is finding and closing the leak in the application code.

Still Not Working?

If you've raised the limit and confirmed the count isn't leaking, but the error persists, check whether you're also hitting the system-wide limit rather than the per-process one — fs.file-max caps the total number of file descriptors across the entire system, independent of any single process's own limit:

cat /proc/sys/fs/file-max
sudo sysctl -w fs.file-max=2097152

To make this change persistent across reboots, add fs.file-max = 2097152 to /etc/sysctl.conf.

If the process runs inside a Docker container, be aware that limits set inside the container can be further constrained by the host's own settings, or by explicit limits passed to docker run. Confirm the container itself sees the limit you expect:

docker exec your-container sh -c "ulimit -n"

If this shows a lower value than what you configured on the host, pass the limit explicitly when starting the container instead of relying on it inheriting host settings automatically:

docker run --ulimit nofile=65536:65536 your-image

If you're debugging a suspected leak rather than a genuine high-concurrency need, tools like lsof -p <pid> combined with periodic snapshots over time can help identify a pattern — for example, noticing that the same file path or the same type of database connection keeps appearing repeatedly without ever closing points directly at the specific code path responsible, turning a vague "too many open files" error into a concrete, fixable bug rather than something you keep working around by raising limits indefinitely.