Bash error: "fork: retry: Resource temporarily unavailable"
Fix "fork: retry: Resource temporarily unavailable" in Bash — usually a process ulimit or PID limit. How to diagnose it and raise the limits safely.
Error String
bash: fork: retry: Resource temporarily unavailable
Tldr
This means the kernel refused to create a new process (fork) because a limit was hit — most often the per-user process/thread ulimit (`ulimit -u`), the system-wide PID max, or available memory being exhausted. Check `ulimit -u`, `ps -u $USER | wc -l`, and system memory, then raise the limit or reduce concurrent processes.
Cause
Every command Bash runs, plus every subshell, pipeline stage, and background job, requires a fork(). If the calling user has already reached their max-processes ulimit (RLIMIT_NPROC), or the kernel is low on memory, or /proc/sys/kernel/pid_max is exhausted system-wide, fork() fails with EAGAIN, which Bash reports as this message. Runaway loops that spawn processes without limits (fork bombs, unbounded parallel xargs/GNU parallel jobs) are the classic trigger.
Repro
#!/usr/bin/env bash
for i in $(seq 1 100000); do
sleep 60 & # spawns unbounded background processes
done
# eventually: bash: fork: retry: Resource temporarily unavailableFix
#!/usr/bin/env bash
set -euo pipefail
# Check your current process limit and usage
ulimit -u
ps -u "$USER" | wc -l
# Raise the soft limit for this session (needs permission via limits.conf for a permanent change)
ulimit -u 4096
# Better: bound concurrency instead of raising limits
seq 1 100000 | xargs -P 8 -I{} sleep 1
# Check overall memory pressure too
free -hExplanation
Fixing the immediate symptom by raising ulimit -u only postpones the problem if the root cause is an unbounded loop spawning processes. Prefer bounding concurrency with `xargs -P N` or GNU parallel `-j N`, and reserve raising RLIMIT_NPROC in /etc/security/limits.conf for services that legitimately need many processes/threads.
Faq
Q
Is this the same error as running out of memory?
A
They can look similar since both prevent fork(), but memory exhaustion shows up in `free -h` and dmesg OOM-killer logs, while a process limit shows up in `ulimit -u` vs. `ps -u $USER | wc -l`. Check both.
Q
Why does killing background jobs not immediately fix it?
A
Zombie or still-terminating processes can briefly hold slots even after you kill them. Wait a moment and recheck with `ps -u $USER | wc -l`, or use `wait` in scripts to reap children properly.
Q
How do I make a ulimit change permanent?
A
Session-scoped `ulimit -u N` only lasts for that shell. For a lasting change, add entries to /etc/security/limits.conf (e.g. "username soft nproc 4096") and ensure pam_limits is enabled.