Fix User Process Limit Exceeded (ulimit) on Linux
You hit the max user processes limit. Usually because of bad ulimit settings or a fork bomb. Here's how to find and fix it fast.
1. Check and Raise Your ulimit Settings (Most Common Fix)
Nine times out of ten, this error is just a misconfigured ulimit -u setting. The kernel is saying 'no more processes for you.' If you're on a busy server or a desktop running lots of apps, the default limit is way too low.
Run this to see your current soft and hard limits:
ulimit -Su
ulimit -Hu
If the soft limit is 1024 or 4096 and you're running something like a CI agent, a database, or a monitoring tool, you'll hit the wall fast. The fix is to raise it in /etc/security/limits.conf.
Add these lines (replace username with the actual user, or use * for all):
username soft nproc 65536
username hard nproc 65536
Then log out and back in. Verify with ulimit -Su. If it still shows the old value, check that PAM's pam_limits.so is loaded. Many modern distros skip it in /etc/pam.d/common-session or /etc/pam.d/sshd. Add this line:
session required pam_limits.so
I've been burned by this more times than I can count. Always check PAM first if limits.conf doesn't stick.
2. systemd User Limits (The Sneaky One)
If you're using a systemd-based distro (Ubuntu 18.04+, RHEL 7+, any modern one), /etc/security/limits.conf doesn't apply to services started by systemd. Systemd has its own limit system, and it's often the culprit.
For a user session, systemd enforces UserTasksMax in /etc/systemd/logind.conf. Default is 33% of the global pid_max, which might be around 12,000 on a default kernel. That's fine for most, but if you're doing heavy threading (like web servers, browsers with 100 tabs), you can hit it.
Check it:
systemctl show user-$(id -u).slice | grep TasksMax
To raise it, edit /etc/systemd/logind.conf, set:
UserTasksMax=100000
Then restart logind (kills your session, so do it remotely or plan ahead):
systemctl restart systemd-logind
For a specific service, add TasksMax=infinity or a number in the service unit file under [Service]. Then systemctl daemon-reload and restart the service.
3. Fork Bomb or Runaway Process (The Emergency Fix)
If the error came suddenly and the system is barely responding, you might have a fork bomb or a buggy process that's spawning hundreds of children. This happens when a script has an infinite loop calling fork(), or a bad while true in shell.
First, check the process tree:
ps aux --forest | grep -c '^'
watch -n 1 'ps auxww | wc -l'
If you see one user owning thousands of processes, grab the PID of the parent (usually the one with the highest count) and kill it:
kill -9
If that doesn't work (system too slow), you can use systemd-cgtop to find the offending cgroup and stop it:
systemd-cgtop
systemctl stop user-1000.slice
Replace 1000 with the UID of the problematic user. That'll nuke all their processes.
If the whole machine is locked, try sysctl kernel.pid_max to see the global limit. Default is 32768 on many systems. You can raise it live:
sysctl -w kernel.pid_max=65536
But that's a band-aid. Find the root cause. Add this to /etc/sysctl.conf to make it permanent.
Pro tip: If you're running a Java app or a database like PostgreSQL, they create tons of threads. Always raise both the user limit and systemd limit before deploying.
Quick Reference Summary Table
| Cause | Check Command | Fix Location |
|---|---|---|
| ulimit too low | ulimit -Su |
/etc/security/limits.conf |
| systemd user limit | systemctl show user-UID.slice | grep TasksMax |
/etc/systemd/logind.conf or service unit |
| Fork bomb / runaway | ps aux --forest |
Kill parent PID or user slice |
| Global pid_max | sysctl kernel.pid_max |
/etc/sysctl.conf |
Remember: limits are your friend. They prevent one bad app from taking down the whole machine. Set them high enough for your workload, but don't go infinite unless you're 100% sure. And test after every reboot — I've had configs vanish after updates.
Was this solution helpful?