Introduction

When Nginx worker processes exhaust their available file descriptors, the error log fills with "too many open files" messages. Each client connection, log file, and upstream connection consumes a file descriptor. The default limit of 1024 is quickly reached on busy servers. The error appears as:

bash
2026/04/08 19:15:33 [alert] 6789#0: *12345 socket() failed (24: Too many open files) while connecting to upstream

Symptoms

  • Nginx error log shows "Too many open files" alert messages
  • New client connections are silently dropped
  • Nginx worker process logs (24: Too many open files) errors
  • Server appears to stop accepting new connections while existing ones remain active
  • lsof -p <nginx-pid> | wc -l shows file descriptor count at or near the limit

Common Causes

  • Default OS nofile soft limit of 1024 per process
  • High-traffic server serving thousands of concurrent connections
  • Log files, upstream connections, and static files all consuming descriptors
  • Systemd service not configured with LimitNOFILE override
  • Application leaks file descriptors (e.g., not closing upstream connections)

Step-by-Step Fix

  1. 1.Check current file descriptor limits for the Nginx master process:
  2. 2.```bash
  3. 3.cat /proc/$(cat /var/run/nginx.pid)/limits | grep "open files"
  4. 4.`
  5. 5.This shows both soft and hard limits currently applied.
  6. 6.Check how many file descriptors Nginx is actually using:
  7. 7.```bash
  8. 8.ls /proc/$(cat /var/run/nginx.pid)/fd | wc -l
  9. 9.`
  10. 10.If this number is close to the soft limit, you need to increase the limit.
  11. 11.Configure systemd LimitNOFILE override. Create /etc/systemd/system/nginx.service.d/override.conf:
  12. 12.```ini
  13. 13.[Service]
  14. 14.LimitNOFILE=65535
  15. 15.LimitNOFILESoft=65535
  16. 16.`
  17. 17.Then reload systemd and restart Nginx:
  18. 18.```bash
  19. 19.sudo systemctl daemon-reload
  20. 20.sudo systemctl restart nginx
  21. 21.`
  22. 22.Set the system-wide file descriptor limit in /etc/sysctl.conf:
  23. 23.`
  24. 24.fs.file-max = 2097152
  25. 25.`
  26. 26.Apply with sudo sysctl -p. This sets the maximum for the entire system.
  27. 27.Configure user-level limits in /etc/security/limits.conf:
  28. 28.`
  29. 29.nginx soft nofile 65535
  30. 30.nginx hard nofile 65535
  31. 31.`
  32. 32.Note: These are ignored by systemd services; use the systemd override instead.
  33. 33.Tune Nginx worker_connections to match. In /etc/nginx/nginx.conf:
  34. 34.```nginx
  35. 35.events {
  36. 36.worker_connections 4096;
  37. 37.}
  38. 38.`
  39. 39.Each worker needs at least worker_connections * 2 file descriptors (one for client, one for upstream).

Prevention

  • Monitor file descriptor usage with a cron job: ls /proc/$(cat /var/run/nginx.pid)/fd 2>/dev/null | wc -l
  • Set up alerts when usage exceeds 70% of the limit
  • Use worker_rlimit_nofile 65535; in the Nginx main context as an additional safeguard:
  • ```nginx
  • worker_rlimit_nofile 65535;
  • events {
  • worker_connections 4096;
  • }
  • `
  • Review application upstream connection pooling to avoid leaked connections
  • Keep sysctl.conf and systemd overrides under version control for reproducible server configuration