BuildNot yet confirmed elsewhere1 publisher2 min readPublished
Rootful Podman's restart policy stalls after one restart for ID-mapped containers on AppArmor hosts
Rootful Podman restarts a container with its own --uidmap mapping once on an AppArmor host, then leaves it exited with RestartCount stuck at 1. A dev.to reproduction on Debian found the policy still looks configured afterwards, so a service relying on it can stay down unnoticed.
The Engineer · Build desk

What happened
- The podman container cleanup process that should restart the container fails with an error saying AppArmor is disabled, on a host where it is enabled.
- A mapped container on --restart on-failure:3 whose command exits with status 1 also stops at one restart.
- In a 25-second test, the same container without the mapping, or with apparmor=unconfined, reached five restarts and was still running.
- A Quadlet unit with UIDMap= and Restart=always was restarted by systemd every time.
- The write-up reproduced it on Debian 13 with podman 5.4.2, and upstream report podman#29925 shows it on Ubuntu 26.04 with 5.7.0 and 6.1.3.
Why it matters
- constraint A test that kills an affected container once and watches it return will pass, so proving a restart policy on these hosts takes at least two exits.
- exposure The trigger is a hardening choice: --uidmap is how operators run rootful containers as unprivileged host IDs, so the more carefully isolated services are the ones that lose automatic recovery.
- constraint Upstream has no diagnosis yet and every release tested shows the stall, so there is no Podman version known to fix it.
According to the dev.to write-up, conmon launches the cleanup process as `podman container cleanup --stopped-only <id>` when the container exits [12]. The AppArmor message comes from the AppArmor package in containers/common [18]. There, IsEnabled() returns whether IsSupported() succeeds [18]. In v0.62.2, the version in Debian, IsSupported() runs three checks in order: the process must not be rootless, the kernel must report AppArmor as on, and a lookup for the apparmor_parser binary must succeed [18]. The author notes that the wording points at the host configuration rather than at Podman [14]. On the test VM, /sys/module/apparmor/parameters/enabled read Y [9].
The obvious suspect is the rootless check. The write-up's strace of conmon rules it out on the evidence available. It shows the cleanup process running as root inside the host user namespace, with no Podman user-namespace variable set in its environment; the process never re-executed itself and never called unshare [19]. Effective capabilities for conmon, CapEff 000001ffffffffff in the host user namespace, matched between the mapped and the plain container [20]. If the rootless check passes, the failure sits in one of the other two: the kernel's AppArmor flag or the apparmor_parser lookup [22].
After the stall, podman inspect still shows the policy as always, and the event stream holds the one restart event [13]. Without --syslog on the command that created the container, the cleanup process has nowhere to report the error. It never reaches the journal, podman logs or the event stream [3]. Running podman start by hand brings the container back without complaint [10].
The reproduction ran as root on a Debian 13.7 VM with kernel 6.12.111, crun 1.21, conmon 2.1.12 and containers-common 0.62.2 [8]. Each of its three alpine test containers exits after four seconds and carries --restart always [8].
Most Podman hosts never hit this. Rootless Podman does not use AppArmor profiles, and Fedora and RHEL use SELinux [15]. The author did not test other ways of giving a container its own mapping, such as --userns=auto [17].
The author's toolkit includes check-podman-restart-userns.sh to list containers that are stuck or will get stuck [7]. Setting --security-opt apparmor=unconfined keeps restarts going by taking the AppArmor profile off the container [5]. We think Quadlet is the right fix for hosts that adopted --uidmap for isolation. With Quadlet, the unit keeps its UIDMap= line and systemd owns the restart [6].
What to watch
- Whether podman#29925 pins the failure to a specific IsSupported() check and names a release that fixes it.
- Results for --userns=auto and other mapping options; a stall there widens the affected set beyond --uidmap/--gidmap users.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence62
- Adoption
- Insufficient
- Hype gap−5
- Incentives20
- Confidence58
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
On a host with AppArmor enabled, a rootful Podman container with its own ID mapping (--uidmap/--gidmap) and a restart policy is restarted once at most; when it exits the second time it stays exited, podman events shows died, restart and then nothing, and RestartCount stops at 1.
- [2]
The process that should restart the container, podman container cleanup, fails with: profile "containers-default-0.62.2" specified but AppArmor is disabled on the host, although AppArmor is enabled.
- [3]
The error is logged only if the container was created with podman --syslog; without it the cleanup process has no place to report the error, so it is not in the journal, in podman logs, or in the events.
- [4]
Reproduced on Debian 13 with Debian's podman 5.4.2; the upstream report, podman-container-tools/podman#29925, is on Ubuntu 26.04 with 5.7.0 and 6.1.3, so it is not Ubuntu-specific or new.
- [5]
The same container without the mapping, or with --security-opt apparmor=unconfined, kept restarting. Twenty-five seconds after start: rtest-userns exited restarts=1; rtest-unconfined running restarts=5 apparmor=unconfined; rtest-plain running restarts=5.
- [6]
A Quadlet unit with UIDMap= and Restart=always was restarted by systemd every time.
- [7]
The author's toolkit includes check-podman-restart-userns.sh, which lists containers that are stuck or will get stuck.
- [8]
Test setup: disposable Debian 13.7 VM, kernel 6.12.111, podman 5.4.2, crun 1.21, conmon 2.1.12, containers-common 0.62.2, all as root; three alpine:3.22 containers that exit after four seconds, each with --restart always.
- [9]
On the test VM AppArmor was enabled: /sys/module/apparmor/parameters/enabled was Y.
- [10]
podman start rtest-userns from a shell started the stuck container without complaint.
- [11]
--restart on-failure:3 on a mapped container whose command exits 1 stopped the same way, at restarts=1.
- [12]
The failing process is podman ... container cleanup --stopped-only <id>, which conmon runs when the container exits.
- [13]
The event stream has a restart event, podman inspect shows the policy as always, and the first crash is handled, so a quick test that kills the container once and watches it come back passes.
- [14]
The error says AppArmor is disabled on a host where it plainly is not, which points at the host configuration rather than at Podman.
- [15]
Rootless Podman does not use AppArmor profiles; Fedora and RHEL use SELinux; containers without their own mapping restart fine.
- [16]
The bug takes rootful Podman, an AppArmor distribution, and --uidmap/--gidmap, which is exactly what people reach for when they want rootful containers to run as unprivileged host IDs.
- [17]
Other ways of giving a container its own mapping, such as --userns=auto, were not tested.
- [18]
The message comes from containers/common's AppArmor package. IsEnabled() returns whether IsSupported() succeeds, and IsSupported() (v0.62.2, the version in Debian) checks three things in order: that the process is not rootless, that the kernel reports AppArmor as enabled, and that the apparmor_parser binary can be found.
- [19]
Traced with strace -f on conmon as the container exited, the cleanup process ran as root, in the host's user namespace, with no Podman user-namespace variable in its environment, and it did not re-execute itself or call unshare.
- [20]
conmon's capabilities were the same for the mapped and the plain container (CapEff: 000001ffffffffff, host user namespace).
- [21]
The upstream report does not explain the failure.
- [22]
If the cleanup process passes IsSupported()'s rootless check, the failing check is one of the remaining two: the kernel reporting AppArmor as enabled, or the apparmor_parser binary lookup.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toRootful Podman restarts a --uidmap container once on an AppArmor host, then gives up
1 article · October 10, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.