What the message looks like
accept4() failed (24: Too many open files)Common causes
- Per-process limit too low, often 1024 by default.
- Limit raised in
/etc/security/limits.conf– which does not apply to systemd services. - File descriptor leak: the application does not close files or connections.
- Many concurrent connections, e.g. WebSockets or slow upstreams.
- In nginx:
worker_connectionshigher than the workers' limit.
Check
- Show the actual limit of the running process
cat /proc/$(pgrep -o nginx)/limits | grep 'open files' - Count currently open descriptors
ls /proc/$(pgrep -o nginx)/fd | wc -l - Show the limit from the systemd unit
systemctl show nginx.service -p LimitNOFILE - Find processes with the most open files
lsof -n 2>/dev/null | awk '{print $1}' | sort | uniq -c | sort -rn | head
Fix
- Set the limit for the service:
systemctl edit nginxwith[Service]LimitNOFILE=65535, then restart. - For nginx also set
worker_rlimit_nofile 65535;. - If the number of open descriptors keeps rising, look for a leak instead of only raising the limit.
- Adjust
limits.conffor login shells, always systemd for services. - Check the system-wide limit:
cat /proc/sys/fs/file-nr.
FAQ
Why does ulimit -n show a high value but the service still fails?
ulimit shows your shell's limit. Services inherit limits from systemd. What counts is /proc/PID/limits of the running process.
How high can the limit be?
65535 is generous for most services. Higher is possible but hides leaks. Watch the number of open descriptors over time.