{"record":{"id":"cbacfeebbae7fa69","repo":"podman-container-tools/podman","slug":"cannot-fork-m","errorCode":null,"errorMessage":"cannot fork: %m\n","messagePattern":"cannot fork: %m\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rootless/rootless_linux.c","lineNumber":1153,"sourceCode":"  argv = get_cmd_line_args (NULL);\n  if (argv == NULL)\n    {\n      fprintf (stderr, \"cannot read argv: %m\\n\");\n      _exit (EXIT_FAILURE);\n    }\n\n  argv0 = argv[0];\n\n  userns_fd = open_namespace (pid_to_join, \"user\");\n  if (userns_fd < 0)\n    return userns_fd;\n  mntns_fd = open_namespace (pid_to_join, \"mnt\");\n  if (mntns_fd < 0)\n    return mntns_fd;\n\n  pid = fork ();\n  if (pid < 0)\n    fprintf (stderr, \"cannot fork: %m\\n\");\n\n  if (pid)\n    {\n      int f;\n\n      for (f = 3; f <= open_files_max_fd; f++)\n        if (is_fd_inherited (f))\n          close (f);\n      if (do_socket_activation)\n        {\n          unsetenv (\"LISTEN_PID\");\n          unsetenv (\"LISTEN_FDS\");\n          unsetenv (\"LISTEN_FDNAMES\");\n        }\n\n      return pid;\n    }\n","sourceCodeStart":1135,"sourceCodeEnd":1171,"githubUrl":"https://github.com/podman-container-tools/podman/blob/a2409076ef2fef60ad9ac046375dedc7d9410ef4/pkg/rootless/rootless_linux.c#L1135-L1171","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["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","Check and raise the user process limit: ulimit -u (or prlimit --nproc)","Kill leaked processes: podman ps -a, podman rm -a, pkill -f _PODMAN_PAUSE","If reproducible with healthy limits, report upstream: the pid < 0 branch should _exit(EXIT_FAILURE) right after the fprintf"],"exampleFix":"// before (rootless_linux.c:1151)\n  pid = fork ();\n  if (pid < 0)\n    fprintf (stderr, \"cannot fork: %m\\n\");\n  if (pid) { ... }\n\n// after\n  pid = fork ();\n  if (pid < 0)\n    {\n      fprintf (stderr, \"cannot fork: %m\\n\");\n      return -1;\n    }\n  if (pid) { ... }","handlingStrategy":"retry","validationCode":"# check pid limits before heavy rootless use\ncat /sys/fs/cgroup/pids.max 2>/dev/null || cat /sys/fs/cgroup/pids/pids.max 2>/dev/null\nulimit -u\npgrep -fc _PODMAN_PAUSE   # leaked pause processes count against the limit","typeGuard":null,"tryCatchPattern":"# at the shell/automation level: EAGAIN-class fork failures are transient\nfor i in 1 2 3; do\n  podman \"$@\" && break\n  sleep $((i*i)); pkill -f _PODMAN_PAUSE 2>/dev/null\ndone","preventionTips":["Raise systemd user-slice TasksMax= and cgroup pids.max above your container workload peak","Reap stopped containers and leaked pause processes regularly (podman rm -a; pkill -f _PODMAN_PAUSE)","Set sane `ulimit -u` values in the user's limits.conf"],"tags":["podman","rootless","process-limits","fork","cgroups"],"backgroundTag":null,"analyzedSha":"a2409076ef2fef60ad9ac046375dedc7d9410ef4","analyzedAt":"2026-08-15T15:57:05.625Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}