podman-container-tools/podman · error

cannot fork: %m

Error message

cannot fork: %m

What it means

In reexec_userns_join, fork() before the namespace-join dance failed; %m prints the errno (EAGAIN when RLIMIT_NPROC or the cgroup pids controller limit is hit, ENOMEM otherwise). Note the code prints the message but does not return/_exit here — with pid = -1 the following `if (pid)` branch is still taken (non-zero), inherited fds get closed, and -1 is returned to the Go caller; the missing early exit is a latent upstream wart worth reporting.

Source

Thrown at pkg/rootless/rootless_linux.c:1153

  argv = get_cmd_line_args (NULL);
  if (argv == NULL)
    {
      fprintf (stderr, "cannot read argv: %m\n");
      _exit (EXIT_FAILURE);
    }

  argv0 = argv[0];

  userns_fd = open_namespace (pid_to_join, "user");
  if (userns_fd < 0)
    return userns_fd;
  mntns_fd = open_namespace (pid_to_join, "mnt");
  if (mntns_fd < 0)
    return mntns_fd;

  pid = fork ();
  if (pid < 0)
    fprintf (stderr, "cannot fork: %m\n");

  if (pid)
    {
      int f;

      for (f = 3; f <= open_files_max_fd; f++)
        if (is_fd_inherited (f))
          close (f);
      if (do_socket_activation)
        {
          unsetenv ("LISTEN_PID");
          unsetenv ("LISTEN_FDS");
          unsetenv ("LISTEN_FDNAMES");
        }

      return pid;
    }

View on GitHub (pinned to a2409076ef)

Solutions

  1. Check the pids limit of the failing podman process's cgroup: cat /sys/fs/cgroup/$(cat /proc/$$/cgroup | cut -d: -f3)/pids.max (cgroup v2) and raise TasksMax/pids.max
  2. Check and raise the user process limit: ulimit -u (or prlimit --nproc)
  3. Kill leaked processes: podman ps -a, podman rm -a, pkill -f _PODMAN_PAUSE
  4. If reproducible with healthy limits, report upstream: the pid < 0 branch should _exit(EXIT_FAILURE) right after the fprintf

Example fix

// before (rootless_linux.c:1151)
  pid = fork ();
  if (pid < 0)
    fprintf (stderr, "cannot fork: %m\n");
  if (pid) { ... }

// after
  pid = fork ();
  if (pid < 0)
    {
      fprintf (stderr, "cannot fork: %m\n");
      return -1;
    }
  if (pid) { ... }
Defensive patterns

Strategy: retry

Validate before calling

# check pid limits before heavy rootless use
cat /sys/fs/cgroup/pids.max 2>/dev/null || cat /sys/fs/cgroup/pids/pids.max 2>/dev/null
ulimit -u
pgrep -fc _PODMAN_PAUSE   # leaked pause processes count against the limit

Try / catch

# at the shell/automation level: EAGAIN-class fork failures are transient
for i in 1 2 3; do
  podman "$@" && break
  sleep $((i*i)); pkill -f _PODMAN_PAUSE 2>/dev/null
done

Prevention

When it happens

Trigger: fork() returns -1: RLIMIT_NPROC (`ulimit -u`) exhausted; systemd user slice TasksMax= or cgroup v2 pids.max reached; ENOMEM from overcommit limits. Reached whenever a rootless podman joins an existing user namespace (e.g. podman system service spawned commands, TryJoinFromEnv path).

Common situations: Leaked pause processes and stopped containers accumulating under the user slice until pids.max; CI runners with tight TasksMax; systems where ulimit -u is set low for the user.

Related errors


AI-assisted analysis of podman-container-tools/podman@a2409076ef (2026-08-15). Data as JSON: /api/errors/cbacfeebbae7fa69. Report an issue: GitHub.