"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
Fixes (2)
Raise the limit for the service properly
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.
Find the process and read its actual limits.
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.
Raise it in the unit, which is the mechanism systemd actually honours.
sudo systemctl edit nginx.serviceAdd these two lines in the editor that opens: [Service] then LimitNOFILE=65535
Reload and restart.
sudo systemctl daemon-reload && sudo systemctl restart nginxRaise 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.
Check the system-wide ceiling is not lower than what you asked for.
cat /proc/sys/fs/file-maxsysctl fs.file-nr
pid=$(systemctl show -p MainPID --value nginx); grep -i 'open files' /proc/$pid/limitsTrack down a descriptor leak
The count climbs steadily and never falls. Raising the limit only delays the failure.
Watch the count over time.
pid=$(pgrep -f myapp | head -1)watch -n5 "ls /proc/$pid/fd | wc -l"
Group the open descriptors by type to see what is accumulating.
sudo ls -l /proc/$pid/fd | awk '{print $11}' | sed 's/[0-9]*$//' | sort | uniq -c | sort -rn | headLook for sockets stuck in CLOSE_WAIT — that pattern means the application is not closing connections the peer has already finished with.
sudo ss -tanp | grep CLOSE-WAIT | head -20CLOSE_WAIT is entirely the local application's responsibility. A large and growing count of them is a code bug, not a tuning problem.
Check for repeatedly opened files that are never closed.
sudo lsof -p $pid | awk '{print $9}' | sort | uniq -c | sort -rn | headRaise the limit as a stopgap so the service survives while the leak is fixed, and add a restart schedule if needed.
Related faults
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.