Go Tests "too many open files" - Fix the FD Limit in CI
By Daniel Zoghalchali·Latchkey
A test run exhausted the process’s file-descriptor limit. Either tests leak descriptors (files, sockets, HTTP bodies not closed) or the runner’s nofile ulimit is too low for the parallelism the suite uses.
What this error means
Tests fail intermittently with too many open files or socket: too many open files, often deep in a test that opens connections or files. It can grow worse as the suite runs, pointing at a leak, or fail immediately under high parallelism, pointing at the limit.
go test output
--- FAIL: TestFetchAll (2.13s)
client_test.go:44: Get "http://...": dial tcp: socket: too many open files
Common causes
Leaked file or socket descriptors
Tests open files, connections, or response bodies without closing them. Across many cases the descriptors accumulate until the limit is hit.
A low nofile ulimit on the runner
Container or minimal runners often set a low nofile soft limit. A parallel suite that legitimately opens many descriptors then exceeds it.
How to fix it
Close descriptors and response bodies
Ensure every opened file, connection, and HTTP body is closed - defer resp.Body.Close() is the usual culprit.
Go
resp, err := http.Get(url)
if err != nil { t.Fatal(err) }
defer resp.Body.Close() // and drain it so the connection is reused
Raise the file-descriptor limit
When the suite legitimately needs many descriptors, raise the soft limit before running tests.
Terminal
ulimit -n 8192
go test ./...
Reduce test parallelism while you investigate
Terminal
go test -p 2 -parallel 2 ./...
How to prevent it
Always close files, connections, and HTTP response bodies in tests.
Set a sensible nofile ulimit on CI runners.
Use httptest servers and shared clients to bound open connections.
Frequently asked questions
What causes ""too many open files""?
Tests open files, connections, or response bodies without closing them. Across many cases the descriptors accumulate until the limit is hit.
How do I fix "too many open files"?
Ensure every opened file, connection, and HTTP body is closed - defer resp.Body.Close() is the usual culprit.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.