A file descriptor is a small integer the kernel hands out for every open file, socket, and pipe a process holds, and each process has a soft and hard limit (ulimit -n).
A Java service that leaks connections or never closes streams (missing try-with-resources, an unbounded HTTP connection pool) keeps accumulating descriptors until open() fails with 'Too many open files,' which surfaces as failed DB connections or dropped sockets. Diagnose with lsof -p <pid> or ls /proc/<pid>/fd | wc -l, raise the limit in limits.conf or the systemd unit's LimitNOFILE, but treat a steadily climbing count as a leak to fix, not just a ceiling to raise.
- Raising ulimit without finding the leak.
- Not checking for unclosed streams or sockets.