Stop your containers from leaking file descriptors into the host
By Saket Jain Published Linux/Unix
Stop your containers from leaking file descriptors into the host
Technical Briefing | 8/7/2026
You probably think your container process is isolated, but if you have ever had a pod mysteriously hit a file descriptor limit despite being nowhere near its process count, you have run into a classic leaky abstraction. I spent three days once chasing an ‘too many open files’ error that persisted even after restarting the application. Turns out, the container was inheriting the host shell’s open fds during the execve syscall, and those stale pipes were sitting there eating up the process limit.
Why execve is the silent killer
When you execute a command in a running container via kubectl exec, you are triggering a sequence that involves the container runtime engine, the shim, and eventually the target binary. If the intermediate processes are sloppy with the O_CLOEXEC flag on their internal pipes or sockets, those descriptors don’t get closed when the new binary starts. The kernel sees them as valid references, and they stay attached to your process until it exits.
ls -l /proc/1/fd/
- Check /proc/self/fd inside the container to see if you have unexpected sockets attached to stdin or stdout
- Look for ghost pipe descriptors that refer to the host bridge or container runtime shim
- Verify if your base image entrypoint script is leaking file handles from the setup phase
The kernel doesn’t care if you don’t intend to use those descriptors. It just counts them against the task structure limits. If you’re building custom runtime components or wrapping applications in complex shell scripts, always check your file handle usage after initialization. If you see descriptors pointing to pipes or character devices that don’t belong to your app, you’ve found your leak. Don’t assume the runtime is cleaning up after your entrypoint script; that is your job.
