#29582·podman

`pasta` and `conmon` processes are sometimes left in calling process' control group

Author: mnrxCreated Aug 19, 2026Updated Sep 16, 2026
Software versions
  • Container host

    • Podman: 5.8.3
    • conmon: 2.1.12
    • pasta: commit 587980c
    • systemd: 257.13
    • Running rootless
  • Development machine

    • Podman: 5.8.3

I have a web service (herein called deployer) which invokes Podman (using Node.js' child_process.spawnSync()) to create, start and stop containers. The deployer service is managed as a systemd unit.

Note that in control group paths, I've used /.../ as a shorthand for /sys/fs/cgroup/user.slice/user-33.slice/[email protected]/.

Problem: When I attempt to stop or restart the deployer service, systemd hangs while waiting for all remaining processes in the control group /.../app.slice/deployer.service to exit. This never happens, since the conmon and pasta processes created by Podman when deployer starts containers are left in the control group. conmon is not moved to its own libpod-conmon-<CONTAINER_ID>.scope control group as it usually is.

After 60 seconds, systemd kills the conmon and pasta processes, killing the containers they support. With --restart=always set on the containers, they are restarted. That said, no pasta process is created when restarting them, making the containerised application inaccessible over the network.

When running Podman in an SSH session, the pasta process lands in the control group /.../user.slice/podman-<PID>.scope and becomes a child of the system instance of systemd (PID 1). This allows the shell to exit without killing pasta or waiting for it to exit. That said, this transient control group is only supposed to live as long as the podman process does, but is kept alive by pasta.

In some cases—I forget exactly which—the user instance of systemd complains in the journal about "left-over process[es]":

txt
Aug 11 02:20:15 <HOST> systemd[993]: podman.service: Found left-over process 3323 (pasta) in control group while starting unit. Ignoring.
Aug 11 02:20:15 <HOST> systemd[993]: podman.service: Found left-over process 3927 (pasta) in control group while starting unit. Ignoring.
Aug 11 02:20:15 <HOST> systemd[993]: podman.service: Found left-over process 24491 (pasta) in control group while starting unit. Ignoring.
Aug 11 02:20:20 <HOST> systemd[993]: podman.service: Unit process 3323 (pasta) remains running after unit stopped.
Aug 11 02:20:20 <HOST> systemd[993]: podman.service: Unit process 3927 (pasta) remains running after unit stopped.
Aug 11 02:20:20 <HOST> systemd[993]: podman.service: Unit process 24491 (pasta) remains running after unit stopped.

Possible fix: Explicitly move any spawned support processes (e.g., conmon, pasta, slirp4netns perhaps) to a dedicated control group like conmon sometimes is; libpod-support-<CONTAINER_ID>.scope may be a more accurate name.


I've tested several different methods of invoking Podman and recorded the parent processes and control groups of the spawned processes. I've left notes ("⚠️") wherever I think behaviour may not be correct.

  1. Running Podman on development machine using remote system connection.

    podman → SSH connection → sshd-sessionpodman.socketpodman.service → ...

    Details ⚠️
    bash
    podman run \
      --connection=foo \
      --rm \
      --detach \
      --publish=1234:1234 \
      alpine sleep 1000
    
    podman run \
      --connection=foo \
      --rm \
      --tty \
      --interactive \
      --publish=1234:1234 \
      alpine
    Process Parent process Control group
    podman systemd (user instance) /.../app.slice/podman.service
    conmon systemd (user instance) /.../user.slice/libpod-conmon-<CONTAINER_ID>.scope
    pasta systemd (user instance) /.../app.slice/podman.service
    ⚠️ Being daemonless, Podman's service unit should only live as long as the podman process.
    sleep/sh conmon /.../user.slice/libpod-<CONTAINER_ID>.scope/container
  2. Running Podman on the host via SSH session.

    Details ⚠️
    bash
    podman run \
      --rm \
      --detach \
      --publish=1234:1234 \
      alpine sleep 1000
    
    podman run \
      --rm \
      --tty \
      --interactive \
      --publish=1234:1234 \
      alpine
    Process Parent process Control group
    podman sshd-sessionzsh /.../user.slice/podman-<PID>.scope
    conmon systemd (PID 1)
    ⚠️ All other methods cause this process to be parented by the user instance of systemd, not PID 1.
    /.../user.slice/libpod-conmon-<CONTAINER_ID>.scope
    pasta systemd (PID 1)
    ⚠️ See above.
    /.../user.slice/podman-<PID>.scope
    ⚠️ Being transient, Podman's scope unit should only live as long as the podman process.
    sleep/sh conmon /.../user.slice/libpod-<CONTAINER_ID>.scope/container
  3. Running Podman on the host from a user service (deployer).

    Details ⚠️
    bash
    podman run \
      --rm \
      --detach \
      --publish=1234:1234 \
      alpine sleep 1000
    Process Parent process Control group
    podman node /.../app.slice/deployer.service
    conmon systemd (user instance) /.../app.slice/deployer.service
    ⚠️ This process prevents the deployer service from being restarted without killing containers.
    pasta systemd (user instance) /.../app.slice/deployer.service
    ⚠️ See above.
    sleep/sh conmon /.../user.slice/libpod-<CONTAINER_ID>.scope/container
  4. Running Podman with --cgroup-parent on the host from a user service (deployer).

    ⚠️ This option seems to have no effect, even with an explicit --cgroups option. Is the example below incorrect?

    Details ⚠️
    bash
    podman run \
      --rm \
      --detach \
      --publish=1234:1234 \
      --cgroups=enabled \
      --cgroup-parent=user.slice \
      alpine sleep 1000
    Process Parent process Control group
    podman node /.../app.slice/deployer.service
    conmon systemd (user instance) /.../app.slice/deployer.service
    ⚠️ This process prevents the deployer service from being restarted without killing containers.
    pasta systemd (user instance) /.../app.slice/deployer.service
    ⚠️ See above.
    sleep/sh conmon /.../user.slice/libpod-<CONTAINER_ID>.scope/container
  5. Running Podman via systemd-run on the host from a user service (deployer).

    This works but adds some complexity for the caller. deployer only requires this for calls to podman start, not other invocations of Podman.

    Details ⚠️
    bash
    systemd-run \
      --user \
      --scope \
      --slice=user.slice \
      --unit=podman.scope \
      podman run \
        --rm \
        --detach \
        --publish=1234:1234 \
        alpine sleep 1000
    Process Parent process Control group
    podman node /.../user.slice/podman.scope
    conmon systemd (user instance) /.../user.slice/podman.scope
    ⚠️ This works, but differs from the intended control group for this process.
    pasta systemd (user instance) /.../user.slice/podman.scope
    ⚠️ See above.
    sleep/sh conmon /.../user.slice/libpod-<CONTAINER_ID>.scope/container
  6. Running Podman with option --cgroups=split on the host from a user service (deployer).

    ⚠️ This alters the control group hierarchy, but does not move support processes to a separate control group to that which the user service runs in. Each invocation of Podman creates a new "runtime" control group and moves the user service into it, eventually leading to an infinite stack of control groups, e.g., ...deployer.service/runtime/runtime/runtime/[...]/runtime

    Details ⚠️
    bash
    podman run \
      --rm \
      --detach \
      --publish=1234:1234 \
      --cgroups=split \
      alpine sleep 1000
    Process Parent process Control group
    podman node /.../app.slice/deployer.service
    conmon systemd (user instance) /.../app.slice/deployer.service/runtime
    ⚠️ The parent control group is split, and this new "runtime" group is never removed. The user service is also moved to this new group and never moved back.
    pasta systemd (user instance) /.../app.slice/deployer.service/runtime
    ⚠️ See above.
    sleep/sh conmon /.../app.slice/deployer.service/libpod-payload-<CONTAINER_ID>

The system states above were verified with these commands:

  • pstree --compact-not --hide-threads --show-pids --long
  • pstree --compact-not --hide-threads --show-pids --long --show-parents <PID>
  • systemctl --user status
  • systemctl --user status <PID>

In summary:

  • Methods 1 and 2 probably should have the same result, but do not.
  • Methods 3 and 4 have the same result.
  • Method 5 has allowed me to work around this issue.

Source: podman-container-tools/podman