Linux Too Many Open Files Error Troubleshooting: Find the Cause

Linux too many open files error troubleshooting starts with one important fact: the message usually describes a limit, not a full diagnosis. Linux uses file descriptors for regular files, directories, pipes, devices, and network sockets. When a process reaches its allowance, new work can fail even when disk space and memory look normal.

Linux too many open files error troubleshooting on a server operations workstation

This problem can affect a web server, database, mail service, monitoring agent, or custom application. The safest response is to capture evidence first. Then identify whether one process, the whole system, or a service configuration caused the exhaustion.

A useful Linux too many open files error troubleshooting process separates the immediate limit from the behavior that consumed it.

What “too many open files” means

A file descriptor is a small number that a process uses to refer to an open resource. A network connection consumes one or more descriptors. So can a log file, a pipe between processes, or a file opened by an application.

Linux applies more than one limit. A process has a soft limit, which applies now, and a hard limit, which caps how high the soft limit can go without additional authority. The shell command ulimit -n commonly displays the current shell’s open-file limit.

There is also a system-wide file table limit. Check it with:

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

The first command reports kernel file-table usage values. The second shows the system-wide ceiling. These values do not tell you which service consumed the descriptors, so treat them as a starting point rather than a conclusion.

Start Linux too many open files error troubleshooting with evidence

Record the exact error, timestamp, affected service, and whether the failure is constant or intermittent. A short outage after a traffic increase points to a different hypothesis than a gradual rise over several days.

Next, inspect the service and recent logs. For a systemd-managed service, use a service name that matches your server:

systemctl status example.service --no-pager
journalctl -u example.service --since "30 minutes ago" --no-pager

These commands can show descriptor errors, connection failures, crashes, or repeated restarts. The systemctl manual documents service inspection and management options.

Do not assume that restarting the service fixes the cause. A restart may release descriptors temporarily, but an application leak, excessive connection load, or incorrect timeout can return later. Save useful logs before restarting when the system remains stable enough to do so.

Find the process consuming descriptors

Use process-level counts to find an unusually large consumer. The following loop counts entries in each process’s descriptor directory:

for d in /proc/[0-9]*; do
  n=$(find "$d/fd" -maxdepth 1 -type l 2>/dev/null | wc -l)
  [ "$n" -gt 0 ] && printf '%8s %s\n' "$n" "$(basename "$d")"
done | sort -nr | head

Then map a process ID to its command:

ps -p PID -o pid,ppid,user,comm,args

Replace PID with the actual process ID. Reading /proc/PID/fd may require root access, and a busy process can change while you count it. Repeat the check if the result seems surprising.

For a closer view, inspect the descriptor types:

ls -l /proc/PID/fd | head -50

Entries may point to regular files, pipes, deleted files, or sockets. A large socket count suggests connection pressure or a socket leak. Many pipes may indicate child-process or worker-management problems. Numerous deleted files deserve separate investigation; our guide to Linux deleted files that remain open covers that situation.

Check sockets and connection patterns

Network services often consume most of their descriptors through sockets. The ss command can display listening and established sockets, along with useful state information:

ss -s
ss -lntup
ss -tanp

Its first summary helps show overall socket pressure. Its second output lists listening TCP and UDP services when permissions allow. Finally, the third includes TCP states and process details. Review repeated connections, large numbers of CLOSE-WAIT entries, or an unexpected listener.

CLOSE-WAIT often means the remote side closed a connection, but the local application has not closed its socket. It does not prove a leak by itself. A slow worker, blocked cleanup path, or application bug can produce the same symptom.

Compare socket counts with application traffic and service logs. The Linux ss reference explains the command’s socket inspection options. Avoid killing individual connections at random, because that can interrupt legitimate users without correcting application behavior.

Separate process limits from system limits

After identifying the process, check the limits that actually apply to it:

cat /proc/PID/limits | grep -i "open files"
ls -l /proc/PID/fd | wc -l

The first command shows the process’s soft and hard maximum. The second gives a rough current count. Counts can change between commands, so capture them close together and repeat during the failure.

A shell’s result does not automatically describe a daemon. A service launched by systemd may receive limits from its unit configuration, manager settings, or another service supervisor. Likewise, an application started by a container runtime, cron, or a hosting panel may use a different environment.

Check the service’s effective settings:

systemctl show example.service -p LimitNOFILE -p MainPID
systemctl cat example.service

Also review any drop-in files. A configuration value such as LimitNOFILE= changes a service limit, but it does not repair a leak or reduce unnecessary connection growth.

Look for leaks, bursts, and configuration causes

A descriptor leak occurs when software opens resources and fails to close them. Common examples include unclosed files, sockets left in a retry loop, child processes that retain descriptors, and connection pools that grow without a bound.

Measure the trend instead of relying on one snapshot. Record the process descriptor count at regular intervals during normal activity and during the incident. A steady climb points toward a leak or cleanup failure. A sharp spike may indicate traffic, a batch job, a health-check storm, or an upstream outage that caused retries.

Review service settings that control concurrency. Depending on the software, relevant settings may include worker count, connection-pool size, keepalive duration, request timeout, queue depth, and retry limits. Change only settings documented for that application.

Also check for duplicate service instances, stuck workers, and failed dependencies. A service that cannot reach a database or upstream API may open repeated connections while waiting or retrying. Inspecting the application’s own metrics and logs usually provides better evidence than increasing a kernel limit.

If the server also reports file-creation failures, check whether inode exhaustion is involved. Free disk space does not guarantee free inodes. See our guide to Linux inode exhaustion before treating every file-related error as a descriptor problem.

Raise limits only after finding the cause

Increasing a limit can be appropriate when the workload is legitimate and the application closes resources correctly. First confirm the current usage, expected concurrency, available memory, and service documentation. A higher limit lets a process hold more resources; it does not create unlimited capacity.

For a systemd service, an administrator might use a drop-in rather than editing a vendor unit directly:

sudo systemctl edit example.service

Then add a value supported by the application and operating environment:

[Service]
LimitNOFILE=32768

The number above is an example, not a universal recommendation. Save the change, reload the manager, and restart only during an approved maintenance window:

sudo systemctl daemon-reload
sudo systemctl restart example.service
systemctl show example.service -p LimitNOFILE -p MainPID

Validate the effective limit after the restart. Then monitor descriptor usage, error rates, latency, and memory. If a service quickly approaches the new ceiling, stop and investigate rather than repeatedly raising the value.

Check login and system-wide configuration carefully

Interactive shells may obtain limits from PAM or shell configuration. Files such as /etc/security/limits.conf and files under /etc/security/limits.d/ can affect login sessions, but they may not affect a systemd service. A successful test in your SSH session does not prove that a daemon received the same limit.

System-wide kernel settings also require caution. Raising fs.file-max without understanding memory use and workload can hide a growing problem. Review current values, change one setting at a time, document the reason, and define a rollback plan.

If the service runs in a container, verify the container’s descriptor limit and the host’s available capacity separately. If it runs under another supervisor, use that supervisor’s documented configuration. Always verify the running process, not only the configuration file.

A safe recovery checklist

  • Capture the exact error, time, affected service, and recent workload change.
  • Review service logs and confirm whether the failure is recurring.
  • Identify the process with the highest descriptor count.
  • Inspect /proc/PID/limits and compare usage with the soft limit.
  • Classify descriptors as files, pipes, deleted files, or sockets.
  • Review socket states and application connection behavior.
  • Check service, login, container, and system-wide limits separately.
  • Fix leaks, runaway retries, duplicate instances, or bad timeouts first.
  • Raise a limit only when documented workload needs support it.
  • Restart in a planned window and verify the effective setting afterward.

When Linux too many open files error troubleshooting points to a service leak, preserve logs and measurements before another restart. For complex environments, Tech Rescue Ops LLC can help correlate process limits, systemd settings, socket states, and application behavior during a remote Linux server investigation.

Scroll to Top