Error fix · Server errors

nginx "socket() failed (24: Too many open files)" Fix

Fix nginx too many open files errors by raising worker_rlimit_nofile, the systemd LimitNOFILE value and system limits, then verify the real limits on workers.

Error messagesocket() failed (24: Too many open files)

By SiteDownCheck Editorial · Updated October 28, 2026 · 4 min read

Error 24 is EMFILE: a process has hit its limit on open file descriptors. In nginx every client connection, upstream connection, log file and cached file uses one, so a busy server can run into the limit quickly. You will see lines like these in /var/log/nginx/error.log:

2026/10/08 16:05:22 [crit] 1411#1411: accept4() failed (24: Too many open files)
2026/10/08 16:05:22 [alert] 1411#1411: socket() failed (24: Too many open files) while connecting to upstream, client: 203.0.113.9, server: example.com, request: "GET /api HTTP/1.1", upstream: "http://127.0.0.1:3000/api"
2026/10/08 16:05:23 [crit] 1411#1411: *88 open() "/var/www/example.com/css/app.css" failed (24: Too many open files)

Symptoms are intermittent 500 and 502 responses, connections that hang or reset, and static files that suddenly fail even though they exist. Once load drops the problem seems to vanish, which is why it is often misdiagnosed. Nginx is not crashing, it simply cannot open one more descriptor.

Step 1: find the limit the workers actually have

Do not trust ulimit -n in your shell. What matters is the limit on the running nginx worker processes:

ps -o pid,user,cmd -C nginx
sudo grep -i "open files" /proc/1411/limits
sudo ls /proc/1411/fd | wc -l

If the count is close to the "Max open files" soft limit, you have confirmed the problem. A common value you will see is 1024, which is the traditional default soft limit.

Step 2: raise the nginx level limit

In /etc/nginx/nginx.conf, in the main (top) context:

worker_rlimit_nofile 65535;

events {
    worker_connections 8192;
}

worker_rlimit_nofile changes the limit for worker processes using setrlimit, so it works even if the service manager limit is low, as long as the hard limit allows it. Keep it at least double worker_connections when proxying, because each proxied request uses two sockets. See nginx worker_connections are not enough for the sizing logic.

Step 3: raise the systemd limit

On current Debian, Ubuntu and RHEL-family systems nginx is started by systemd, and its LimitNOFILE setting caps what the processes can get. Do not edit the packaged unit file. Use an override:

sudo systemctl edit nginx

Add:

[Service]
LimitNOFILE=65535

Save, then apply and restart (a plain reload does not change a service's resource limits):

sudo systemctl daemon-reload
sudo systemctl restart nginx
sudo grep -i "open files" /proc/$(cat /run/nginx.pid)/limits

The last command shows the master process limit. Check a worker the same way as in step 1. Without systemd, the equivalent is /etc/security/limits.conf or a file in /etc/security/limits.d/ with lines like nginx soft nofile 65535 and nginx hard nofile 65535 (use the right user: www-data on Debian and Ubuntu, nginx on RHEL-family). These apply to PAM login sessions and do not reliably reach systemd services, so prefer the unit override.

Step 4: check the system-wide ceiling

There is also a kernel-wide limit:

cat /proc/sys/fs/file-max
cat /proc/sys/fs/file-nr

file-nr shows allocated, unused and maximum handles. On modern kernels file-max is large, but on small containers or VPS plans it can be restricted. To raise it persistently:

echo 'fs.file-max = 2097152' | sudo tee /etc/sysctl.d/90-nofile.conf
sudo sysctl --system

In containers, the limit is set by the container runtime. For Docker, check docker run --ulimit nofile=65535:65535 or the equivalent in your compose or orchestrator settings.

Step 5: find what is consuming descriptors

A higher limit only buys time if something is leaking. Check what a worker holds open:

sudo ls -l /proc/1411/fd | awk '{print $NF}' | sed 's/[0-9]*//g' | sort | uniq -c | sort -rn | head

Mostly socket:[...] entries means connections: look for slow backends, long keepalive_timeout, or abusive clients. Many entries pointing at files under your cache or log directories suggest an open_file_cache setting that is too generous, or log files opened per server block. Per-virtual-host access_log files each use a descriptor, and with hundreds of sites the total grows.

Verify the fix

Repeat step 1 and confirm the new limit on workers, then watch the log:

sudo tail -f /var/log/nginx/error.log | grep -i "open files"

Check the site from outside with the HTTP Status Checker and the Website Health Check. Load-related issues often return, so an uptime monitor on the busiest page gives early warning.

The same errno shows up in other runtimes, for instance Node EMFILE, and the cure is the same pattern: raise the per-process limit and fix leaks.

Next steps

FAQ

Why does ulimit -n show a big number but nginx still fails?

ulimit reports your shell, not the service. systemd applies its own LimitNOFILE to nginx. Read /proc/<worker pid>/limits.

Do I need to restart nginx or just reload?

Restart after changing LimitNOFILE. A reload keeps the master process, which does not pick up new service limits.

What is a reasonable limit?

Tens of thousands is typical (for example 65535) on busy servers. Keep it above twice worker_connections on a proxy.

Can this error affect only static files?

Yes. The open() failure with 24 means a worker could not open the file because it was already at its descriptor limit, not because the file is missing.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

This page is general information written by our editorial team and updated when documentation changes. Servers and providers differ, so test changes safely first. See our editorial policy and disclaimer.