Linux  ·  high  ·  Core system faults

"Too many open files" (EMFILE)

A process hit its file descriptor limit. Sockets count as descriptors, so busy servers hit this long before they run out of actual files.

What you see

A daemon starts refusing connections, logging 'too many open files'. Restarting it fixes things temporarily, then it returns under load.

What is actually wrong

The default per-process soft limit of 1024 is far too low for a network service. Sometimes it is a genuine descriptor leak in the application.

Codes and articles

EMFILEToo many open fileserrno 24accept4: too many open files

Fixes (2)

Raise the limit for the service properly
Shell as root20 minuteslow riskreversible

The count sits at a limit. Note that /etc/security/limits.conf does NOT apply to systemd services — that is why so many attempts at this appear to do nothing.

  1. Find the process and read its actual limits.

    Shell
    pid=$(systemctl show -p MainPID --value nginx)cat /proc/$pid/limits | grep -i 'open files'ls /proc/$pid/fd | wc -l

    Reading /proc/PID/limits is the only reliable answer. ulimit -n in your shell reports your shell's limit, which has nothing to do with the daemon's.

  2. Raise it in the unit, which is the mechanism systemd actually honours.

    Shell
    sudo systemctl edit nginx.service
  3. Add these two lines in the editor that opens: [Service] then LimitNOFILE=65535

  4. Reload and restart.

    Shell
    sudo systemctl daemon-reload && sudo systemctl restart nginx
  5. Raise the application's own limit too if it has one — nginx has worker_connections, and it is capped by the descriptor limit rather than replacing it.

  6. Check the system-wide ceiling is not lower than what you asked for.

    Shell
    cat /proc/sys/fs/file-maxsysctl fs.file-nr
Confirm it workedThe new limit is in effect.
Shell
pid=$(systemctl show -p MainPID --value nginx); grep -i 'open files' /proc/$pid/limits
If you need to undo itsudo systemctl revert nginx.service
Track down a descriptor leak
Shell as root1 hourlow riskreversible

The count climbs steadily and never falls. Raising the limit only delays the failure.

  1. Watch the count over time.

    Shell
    pid=$(pgrep -f myapp | head -1)watch -n5 "ls /proc/$pid/fd | wc -l"
  2. Group the open descriptors by type to see what is accumulating.

    Shell
    sudo ls -l /proc/$pid/fd | awk '{print $11}' | sed 's/[0-9]*$//' | sort | uniq -c | sort -rn | head
  3. Look for sockets stuck in CLOSE_WAIT — that pattern means the application is not closing connections the peer has already finished with.

    Shell
    sudo ss -tanp | grep CLOSE-WAIT | head -20

    CLOSE_WAIT is entirely the local application's responsibility. A large and growing count of them is a code bug, not a tuning problem.

  4. Check for repeatedly opened files that are never closed.

    Shell
    sudo lsof -p $pid | awk '{print $9}' | sort | uniq -c | sort -rn | head
  5. Raise the limit as a stopgap so the service survives while the leak is fixed, and add a restart schedule if needed.

Confirm it workedThe descriptor count is stable under sustained load.
If you need to undo itNone — diagnostic.

Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.