Skip to content
LatchkeyLatchkey home

Self-Healing CI: Recovering "Too Many Open Files" (ulimit)

A "too many open files" failure means the job hit its file-descriptor ceiling - raising the limit or closing handles fixes it, no code change required.

The problem

A step fails with EMFILE: too many open files or Too many open files while opening files, sockets, or watchers. The code is fine; the process exceeded the file-descriptor (ulimit -n) ceiling. A human raises the limit or reduces concurrency and the step passes unchanged.

Typical symptom
Error: EMFILE: too many open files, open '...'
# or
accept: too many open files

Why it happens

Every open file, socket, and file watcher consumes a file descriptor, and the OS caps how many a process may hold. Tools that watch large trees or open many connections in parallel can exceed a low default ulimit -n even though no resource is genuinely scarce.

CI runners often ship with a conservative default descriptor limit, so a step that works locally on a higher limit fails on the runner - a mechanical ceiling, not a bug in your build.

The manual fix

The manual fix is to raise the descriptor limit or reduce open handles, then retry:

  1. Raise the soft file-descriptor limit (e.g. ulimit -n) for the step.
  2. Reduce concurrency so fewer files/sockets are open simultaneously.
  3. Ensure tooling closes handles and uses efficient file watching.
Manual fix
ulimit -n 65535
# then run the step

How this gets automated

An EMFILE has a clear descriptor-exhaustion signature, and the safe response is to provide headroom and retry. A self-healing CI pipeline detects the open-files limit condition, retries the step with an adequate descriptor limit, and only escalates if the exhaustion recurs - which would indicate a genuine descriptor leak rather than a low default.

Frequently asked questions

What causes Self-Healing CI: recovering "Too many open Files" (ulimit)?
A step fails with EMFILE: too many open files or Too many open files while opening files, sockets, or watchers. The code is fine; the process exceeded the file-descriptor (ulimit -n) ceiling. A human raises the limit or reduces concurrency and the step passes unchanged.
How do I fix Self-Healing CI: recovering "Too many open Files" (ulimit) manually?
[object Object]
Can Self-Healing CI: recovering "Too many open Files" (ulimit) be fixed automatically?
An EMFILE has a clear descriptor-exhaustion signature, and the safe response is to provide headroom and retry. A self-healing CI pipeline detects the open-files limit condition, retries the step with an adequate descriptor limit, and only escalates if the exhaustion recurs - which would indicate a genuine descriptor leak rather than a

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card