podman-container-tools/podman · error
fork: %m
Error message
fork: %m
What it means
exec_binary() — used to run pre-exec hook binaries during podman's rootless re-exec — failed at fork() before it could exec the hook; %m is strerror(errno), almost always EAGAIN (RLIMIT_NPROC / cgroup pids.max / systemd TasksMax exhausted) or ENOMEM. Pre-exec hooks run only when /etc/containers/podman_preexec_hooks.txt exists, from LIBEXECPODMAN/pre-exec-hooks, ETC_PREEXEC_HOOKS, or $PODMAN_PREEXEC_HOOKS_DIR. The whole podman invocation exits with EXIT_FAILURE.
Source
Thrown at pkg/rootless/rootless_linux.c:375
ret = save_ns_handles (ns_handles_path, &handles);
saved_errno = errno;
close (lock_fd);
lock_fd = -1; /* Prevent cleanup from running. */
errno = saved_errno;
return ret;
}
/* exec the specified executable and exit if it fails. */
static void
exec_binary (const char *path, char **argv, int argc)
{
int r, status = 0;
pid_t pid;
pid = fork ();
if (pid < 0)
{
fprintf (stderr, "fork: %m\n");
exit (EXIT_FAILURE);
}
if (pid == 0)
{
size_t i;
char **newargv = malloc ((argc + 2) * sizeof(char *));
if (!newargv)
{
fprintf (stderr, "malloc: %m\n");
exit (EXIT_FAILURE);
}
newargv[0] = (char*) path;
for (i = 0; i < argc; i++)
newargv[i+1] = argv[i];
newargv[i+1] = NULL;
errno = 0;
execv (path, newargv);View on GitHub (pinned to a2409076ef)
Solutions
- Raise the limits for the rootless user: ulimit -u, systemd TasksMax (user slice), or the session pids.max
- Kill leaked processes/zombies of that user to free slots, then retry the podman command
- If hooks are not needed, remove /etc/containers/podman_preexec_hooks.txt or the hooks directories to skip the fork entirely
- Verify current usage: ps -u USER -L | wc -l vs cat /sys/fs/cgroup/.../pids.max
Example fix
# before: user slice tasks exhausted systemctl status user-1000.slice # Tasks: 4911/4915 # after sudo systemctl set-property user-1000.slice TasksMax=infinity podman ps
Defensive patterns
Strategy: retry
Validate before calling
# EAGAIN at fork is the norm — verify process headroom before invoking podman
#!/bin/sh
uid=$(id -u)
slice="/sys/fs/cgroup/user.slice/user-${uid}.slice"
max=$(cat "$slice/pids.max" 2>/dev/null || echo max)
[ "$max" = max ] || {
cur=$(cat "$slice/pids.current" 2>/dev/null || echo 0)
[ "$cur" -lt $((max - 10)) ] || { echo "user slice pids nearly full: $cur/$max" >&2; exit 1; }
}
exec podman "$@" Try / catch
#!/bin/sh
i=0
while ! podman "$@" 2>err.log; do
grep -q 'fork: Resource temporarily unavailable\|fork: EAGAIN' err.log || { cat err.log >&2; exit 1; }
i=$((i+1)); [ $i -le 3 ] || { cat err.log >&2; exit 1; }
sleep 2
done Prevention
- Raise TasksMax for the rootless user slice (systemctl set-property user-UID.slice TasksMax=...) or the session pids.max
- If pre-exec hooks are not used, remove /etc/containers/podman_preexec_hooks.txt — no indicator file means no hook forks at all
- Keep an eye on thread-heavy workloads sharing the user slice; they can starve podman's re-exec of its single fork
When it happens
Trigger: Rootless podman re-exec with pre-exec hooks configured (indicator file /etc/containers/podman_preexec_hooks.txt present) while the user's process/thread budget is exhausted: ulimit -u hit, systemd user slice TasksMax reached, or cgroup pids.max full — fork() returns EAGAIN and podman aborts.
Common situations: Leaky workloads spawning threads until TasksMax; monitoring agents looping podman as a rootless user near nproc limits; systems where pids cgroup of the user session is shared and saturated; heavier-than-expected hook directories multiplying processes.
Related errors
AI-assisted analysis of podman-container-tools/podman@a2409076ef (2026-08-15).
Data as JSON: /api/errors/c971abc5a71092e9.
Report an issue: GitHub.