podman-container-tools/podman · error
open /proc/1/ns/user: %m
Error message
open /proc/1/ns/user: %m
What it means
With join_userns set (container has its own user namespace, e.g. rootless containers or --userns), the fork_exec_ps() child tries open("/proc/1/ns/user") after entering the container's PID namespace: PID 1 is the container's init, and its ns/user file identifies the container's user namespace to join. %m is strerror(errno): ENOENT/ESRCH when there is no such PID (container init exited), EACCES when procfs is mounted with hidepid or ptrace_scope/Yama blocks access to other processes' ns files.
Source
Thrown at libpod/container_top_linux.c:83
fprintf (stderr, "fork: %m");
exit (special_exit_code);
}
if (pid == 0)
{
r = mount ("proc", "/proc", "proc", 0, NULL);
if (r < 0)
{
fprintf (stderr, "mount proc: %m");
exit (special_exit_code);
}
if (join_userns)
{
// join the userns to make sure uid mapping match
// we are already part of the pidns so so pid 1 is the main container process
r = open ("/proc/1/ns/user", O_CLOEXEC | O_RDONLY);
if (r < 0)
{
fprintf (stderr, "open /proc/1/ns/user: %m");
exit (special_exit_code);
}
if ((status = setns (r, CLONE_NEWUSER)) < 0)
{
fprintf (stderr, "setns NEWUSER: %m");
exit (special_exit_code);
}
}
/* use execve to unset all env vars, we do not want to leak anything into the container */
execve (argv[0], argv, NULL);
fprintf (stderr, "execve: %m");
exit (special_exit_code);
}
r = waitpid (pid, &status, 0);
if (r < 0)
{View on GitHub (pinned to a2409076ef)
Solutions
- Confirm the container is actually running before sampling: podman inspect -f '{{.State.Status}}' CTOR
- Retry once — a dying init makes this a race; if it persists on a running container, continue below
- On hosts using hidepid, mount /proc without hidepid or exempt the podman user (prochidepid group on some distros)
- Adjust kernel.yama.ptrace_scope or run the top as the container's owner/root if access to /proc/1/ns is denied
Example fix
# before
while true; do podman top web >/tmp/top.log; sleep 1; done
# after (only sample live containers)
while true; do [ "$(podman inspect -f '{{.State.Status}}' web)" = running ] && podman top web >/tmp/top.log; sleep 1; done Defensive patterns
Strategy: validation
Validate before calling
# Only sample live containers; avoids racing a dying container init
#!/bin/sh
for ctr in "$@"; do
st=$(podman inspect -f '{{.State.Status}}' "$ctr" 2>/dev/null) || continue
[ "$st" = running ] || { echo "skip $ctr (state: $st)" >&2; continue; }
podman top "$ctr"
done Prevention
- Gate 'podman top' on State.Status == running — a dying PID 1 makes /proc/1/ns/user vanish
- Avoid hidepid on host /proc mounts, or exempt the podman user from hidepid restrictions
- In poll loops, tolerate single-sample failures (race with shutdown) instead of alerting on them
When it happens
Trigger: 'podman top' on a userns container whose init has just exited or is dying (racing 'podman stop'); hidepid=2 on the host /proc; a Yama ptrace_scope setting denying access to /proc/1 of the new pidns for the unprivileged helper; top run exactly as the container transitions states.
Common situations: Scripts running 'podman top' in a poll loop that races container shutdown; hardened hosts mounting /proc with hidepid; monitoring agents sampling dying containers; rootless sessions after the session's user namespace was torn down.
Related errors
AI-assisted analysis of podman-container-tools/podman@a2409076ef (2026-08-15).
Data as JSON: /api/errors/e44c0b4cf83d2520.
Report an issue: GitHub.