Fix Podman Container Exits Immediately

Tested on Red Hat Enterprise Linux 10.2 (Coughlan)
Package podman-5.8.2-5.el10_2.x86_64
Applies to Linux hosts where podman run fails or a newly started container exits immediately
Privilege Rootful examples on the lab host; exit-code behavior is the same rootless unless noted
Scope Diagnosing immediate container exit — podman ps -a Exited status, exit codes 0, 125, 126, 127, 137, and 139, Podman command exit status versus container State.ExitCode, -d without a long-running PID 1, interactive TTY behavior, podman inspect .State, podman wait, podman logs, podman events, ENTRYPOINT and Cmd, PID 1 shell wrappers, --stop-signal, stop timeout SIGKILL escalation, and restart policy masking. Does not cover logout survival, full OOM tuning, health checks, or general lifecycle command reference.
Related guides Run containers with podman run
Inspect Podman containers

You started a container and it is already gone from podman ps. Before you rebuild the image or change restart policy, read the exit code — it tells you whether Podman failed to launch the workload or the application inside the container terminated on its own.


First check: is the container actually exited?

List every container, including stopped ones:

bash
podman ps -a

Sample output after a short-lived run:

output
CONTAINER ID  IMAGE                                               COMMAND     CREATED        STATUS                    NAMES
3eea890bb8ad  registry.access.redhat.com/ubi9/ubi-minimal:latest  echo hello  1 second ago   Exited (0) 1 second ago   exit-zero

Exited (N) in the STATUS column is your first clue. The number in parentheses is the container exit code — not necessarily the same as the shell exit code from the podman run command that created it.


Podman command exit status vs container exit status

These two numbers answer different questions. Read both when debugging.

Code Meaning
125 Podman itself failed before successfully executing the workload
126 The requested command exists but cannot be invoked
127 The requested command cannot be found in the image
other Normally the exit code returned by the contained process
137 Commonly the process was killed by signal 9 (SIGKILL)
139 Commonly the process terminated from signal 11 (SIGSEGV)

Exit code 125 comes from the podman CLI on the host. For a successfully started workload, Podman normally returns the contained process's exit code. Codes 126 and 127 are special launch-time statuses indicating that the requested command could not be invoked or found. Other codes such as 0, 137, or 139 appear in podman ps -a and in podman inspect after the workload ran.


Exited (0) — the container finished successfully

A container stays alive only while its PID 1 process is running. When that process exits, the container stops — even if exit code is zero.

Run a one-shot command:

bash
podman run --name exit-zero registry.access.redhat.com/ubi9/ubi-minimal:latest echo hello

Sample output:

output
hello

Confirm the stopped state:

bash
podman ps -a --filter name=exit-zero

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND     CREATED        STATUS                   NAMES
3eea890bb8ad  registry.access.redhat.com/ubi9/ubi-minimal:latest  echo hello  1 second ago   Exited (0) 1 second ago  exit-zero

This is not a Podman failure. echo hello did its job and exited normally. For a service you need a long-running foreground process as PID 1 — a web server, database, or your application's main binary.


-d does not make a short-lived program long-running

Detached mode only returns your shell prompt. It does not create a daemon or keep a finished command alive.

bash
podman run -d --name detached-demo registry.access.redhat.com/ubi9/ubi-minimal:latest echo hello

Podman prints the container ID and exits zero on the host. Check running containers:

bash
podman ps

Sample output:

output
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

The container is already gone from the running list. Inspect all containers:

bash
podman ps -a --filter name=detached-demo

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND     CREATED       STATUS                             NAMES
b405d0b731c0  registry.access.redhat.com/ubi9/ubi-minimal:latest  echo hello  1 second ago  Exited (0) Less than a second ago  detached-demo

-d detached the terminal; echo hello still exited immediately as PID 1. The fix is to run the intended long-running process in detached mode, not to add -d to a one-shot command.


Interactive shell without -it

A shell with no TTY and no script to run can exit immediately when it has nothing interactive to do. For automation, pass a command explicitly:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest sh -c 'echo non-interactive'

Sample output:

output
non-interactive

For an interactive session you need -it so Podman allocates a TTY and keeps stdin open:

bash
podman run -it --rm registry.access.redhat.com/ubi9/ubi-minimal:latest sh

Do not use tail -f /dev/null as a generic application fix. Run the real foreground workload your image is meant to serve.


Find the actual exit code

Read the numeric code from container state:

bash
podman inspect --format '{{.State.ExitCode}}' exit-zero

Sample output:

output
0

podman wait blocks until the container stops and prints the same code:

bash
podman wait exit-zero

Sample output:

output
0

For the full state block:

bash
podman inspect --format '{{json .State}}' exit-zero

Sample output (trimmed):

output
{"Status":"exited","Running":false,"OOMKilled":false,"ExitCode":0,"Error":"","StartedAt":"2026-08-23T10:47:11.657404821+05:30","FinishedAt":"2026-08-23T10:47:11.670918828+05:30"}

Useful fields:

  • Status and Running — whether the container is still active
  • ExitCode — what podman ps -a shows in parentheses
  • Error — runtime error text when present
  • OOMKilled — kernel OOM hint for signal-style exits
  • StartedAt / FinishedAt — timing for restart-policy debugging

Exit code 125 — Podman failed before the workload started

Reproduce with an invalid flag:

bash
podman run --does-not-exist registry.access.redhat.com/ubi9/ubi-minimal:latest

Sample output:

output
Error: unknown flag: --does-not-exist
See 'podman run --help'

Check the host shell exit status:

bash
echo $?

Sample output:

output
125

Code 125 means Podman could not complete the requested operation. Common failure classes include:

  • invalid CLI flags
  • storage errors
  • network setup failures
  • runtime failures before the container process starts

Do not diagnose application bugs from 125 — fix the podman invocation or host environment first.


Exit code 126 — command cannot be invoked

Podman found the path but could not execute it. Running a directory as the command triggers this on Podman 5.8.2:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest /tmp

Sample output:

output
Error: crun: the path `/tmp` is not a regular file: Operation not permitted: OCI permission denied

Host exit status:

bash
echo $?

Sample output:

output
126

A script without the execute bit produces the same class of failure:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest sh -c 'printf "#!/bin/sh\necho hi\n" > /tmp/nox.sh && chmod 644 /tmp/nox.sh && /tmp/nox.sh'

Sample output:

output
sh: line 1: /tmp/nox.sh: Permission denied

Possible causes include:

  • missing execute permission on the script or binary
  • attempting to run a directory
  • noexec mounts on the command path
  • interpreter permission problems

For exec format error on binaries, see the dedicated architecture-mismatch troubleshooting path.


Exit code 127 — executable not found in $PATH

Request a command that does not exist in the image:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest command-that-does-not-exist

Sample output:

output
Error: crun: executable file `command-that-does-not-exist` not found in $PATH: No such file or directory: OCI runtime attempted to invoke a command that was not found

Host exit status:

bash
echo $?

Sample output:

output
127

Inspect what the image would have run by default:

bash
podman image inspect --format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}' registry.access.redhat.com/ubi9/ubi-minimal:latest

Sample output:

output
null ["/bin/bash"]

Typical fixes:

  • Install the missing binary into the image
  • Correct ENTRYPOINT or CMD in the Containerfile
  • Use an absolute path when the executable is outside $PATH

Exit code 137 — SIGKILL, not automatically OOM

Start a long-running container:

bash
podman run -d --name kill-demo registry.access.redhat.com/ubi9/ubi-minimal:latest sleep 300

Send SIGKILL:

bash
podman kill --signal KILL kill-demo

Check status:

bash
podman ps -a --filter name=kill-demo

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND     CREATED        STATUS                       NAMES
272965029e84  registry.access.redhat.com/ubi9/ubi-minimal:latest  sleep 300   1 second ago   Exited (137) 1 second ago    kill-demo

Exit code 137 follows the shell convention 128 + 9 for SIGKILL. Common sources include:

  • manual podman kill
  • stop-timeout escalation
  • the kernel OOM killer
  • an external supervisor

137 does not mean OOM by default.

Check whether the kernel reported OOM:

bash
podman inspect --format '{{.State.OOMKilled}}' kill-demo

Sample output:

output
false

OOMKilled: false makes Podman's recorded OOM-kill path less likely; check events and host kernel logs before concluding whether SIGKILL came from podman kill, stop-timeout escalation, an external supervisor, or memory pressure.


Stop timeout and SIGKILL escalation

podman stop sends the stop signal, waits, then escalates to SIGKILL. A slow or unresponsive PID 1 can end at 137:

bash
podman run -d --name stop-demo registry.access.redhat.com/ubi9/ubi-minimal:latest sleep 300

Stop with a five-second grace window:

bash
podman stop --time 5 stop-demo

Sample output:

output
time="2026-08-23T10:50:07+05:30" level=warning msg="StopSignal SIGTERM failed to stop container stop-demo in 5 seconds, resorting to SIGKILL"
stop-demo

Read the final exit code:

bash
podman inspect --format '{{.State.ExitCode}}' stop-demo

Sample output:

output
137

For graceful shutdown details, see Start, stop, and restart containers.


Exit code 139 — SIGSEGV or signal-style crash

Exit 139 usually means 128 + 11 for SIGSEGV. The runtime launched the workload; the process crashed inside the container.

On UBI minimal, a trap handler after kill -11 records exit 139 reliably:

bash
podman run --name segv-trap registry.access.redhat.com/ubi9/ubi-minimal:latest sh -c 'trap "exit 139" 11; kill -11 $$; sleep 1'

Check status:

bash
podman ps -a --filter name=segv-trap

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND               CREATED         STATUS                       NAMES
99f05389e2ce  registry.access.redhat.com/ubi9/ubi-minimal:latest  sh -c trap "exit ...  32 seconds ago  Exited (139) 32 seconds ago  segv-trap

Read the stored code:

bash
podman inspect --format '{{.State.ExitCode}}' segv-trap

Sample output:

output
139

Debug with application logs, library mismatches, and core dumps if enabled — not by treating 139 as a Podman launch failure.


Read the last container logs

Application output often explains non-zero exits faster than inspect alone:

bash
podman logs exit-zero

Sample output:

output
hello

For a longer trail with timestamps:

bash
podman logs --tail 100 --timestamps CONTAINER

See View container logs for follow mode and multi-container cases.


Check Podman events

Events show whether the process died on its own, was killed, or was stopped:

bash
podman events --since 30m --filter container=kill-demo --stream=false

Sample output (trimmed):

output
2026-08-23 10:47:27 +0530 IST container create  272965029e84...
2026-08-23 10:47:28 +0530 IST container start   272965029e84...
2026-08-23 10:47:28 +0530 IST container kill    272965029e84...
2026-08-23 10:47:28 +0530 IST container died     272965029e84...

Look for start, died, stop, kill, and restart in sequence. Full event reference: Monitor container events.


Check the container command

Verify what Podman actually started as PID 1:

bash
podman inspect --format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}' exit-zero

Sample output:

output
null ["echo","hello"]

On Podman 5.8.2 the field is Cmd, not Command. A migrated image may combine ENTRYPOINT with a CMD intended as default arguments — if the entrypoint script exits after setup, the container stops even when the image tag looks like a server.


PID 1 is a shell

When you wrap a command in sh -c, the shell becomes PID 1:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest sh -c 'echo -n "PID1: "; tr "\0" " " < /proc/1/cmdline; echo'

Sample output:

output
PID1: sh -c echo -n "PID1: "; tr "\0" " " < /proc/1/cmdline; echo

A shell as PID 1 may not forward signals the way your application expects, and it exits when the -c script finishes. Prefer exec so the workload replaces the shell:

bash
podman run --rm registry.access.redhat.com/ubi9/ubi-minimal:latest sh -c 'exec sleep 1'

That pattern makes sleep PID 1 instead of leaving an extra shell parent.


--stop-signal

Change the first signal Podman sends during stop:

bash
podman run --stop-signal SIGINT ...

This only affects graceful shutdown — it does not keep a short-lived command running, fix a crashing application, or make a shell forward signals correctly.


Restart policy can hide the original exit

A container with --restart on-failure may exit, restart, and fail again before you notice:

bash
podman run -d --name restart-demo --restart on-failure:3 registry.access.redhat.com/ubi9/ubi-minimal:latest false

Read the policy:

bash
podman inspect --format '{{json .HostConfig.RestartPolicy}}' restart-demo

Sample output:

output
{"Name":"on-failure","MaximumRetryCount":3}

Check final status:

bash
podman ps -a --filter name=restart-demo

Sample output:

output
CONTAINER ID  IMAGE                                               COMMAND  CREATED       STATUS                    NAMES
60bd6226d249  registry.access.redhat.com/ubi9/ubi-minimal:latest  false    2 seconds ago Exited (1) 1 second ago  restart-demo

Pair StartedAt, FinishedAt, and events to reconstruct rapid restart loops.


Diagnostic flow

text
Container missing from podman ps
podman ps -a
Exit 0?
 ├─ yes → command completed / no long-running PID 1
 └─ no
125 on host?
 ├─ yes → Podman or runtime setup error
 └─ no
126 or 127?
 ├─ yes → invocation or PATH problem inside image
 └─ no
137?
 ├─ check OOMKilled, kill, and stop timeout
139?
 ├─ process crash / SIGSEGV
other code
 └─ application-specific exit — read logs

Cleanup

Remove lab containers:

bash
podman rm -f exit-zero detached-demo kill-demo stop-demo restart-demo segv-trap 2>/dev/null

References


Summary

When a Podman container vanishes from podman ps, start with podman ps -a and the code in Exited (N). Zero means the main process finished — often a one-shot command or a detached run without a long-lived PID 1. Host exit 125 means Podman failed before launch; 126 and 127 mean the executable could not run or was missing inside the image.

Codes 137 and 139 usually reflect signals — SIGKILL and SIGSEGV — not automatic OOM or Podman errors. Read State.OOMKilled, podman logs, and podman events together with Entrypoint and Cmd from inspect. When PID 1 is a shell wrapper, use exec in the -c script so signals reach the real application.

For detached services, run the actual foreground server as PID 1. For stop behavior and restart loops, continue with Start, stop, and restart containers.


Frequently Asked Questions

1. Why does my Podman container exit with code 0 immediately?

Exit code 0 means the main process finished successfully. A one-shot command such as echo hello runs, prints output, and exits. That is normal behavior, not a Podman bug. Keep the container running by starting a long-lived foreground process as PID 1, such as a server or sleep only for demos.

2. What is the difference between Podman exit code 125 and 127?

Exit code 125 means Podman failed before the workload started, such as an invalid flag or runtime setup error. Exit code 127 means Podman reached the container runtime, but the requested executable could not be found inside the image, so the workload itself never successfully started. Check podman run flags for 125 and image ENTRYPOINT, CMD, or PATH for 127.

3. Does exit code 137 always mean out of memory?

No. Exit code 137 usually means the process received SIGKILL, which is 128 plus signal 9. Manual podman kill, stop timeout escalation, the kernel OOM killer, or an external service can all produce 137. Check State.OOMKilled in podman inspect before blaming memory limits.

4. Why does podman run -d stop right after start?

The -d flag only detaches your terminal. It does not turn a short command into a daemon. If PID 1 is echo hello or a script that exits, the container stops as soon as that process ends even in detached mode. Run a long-lived foreground command as PID 1 instead.

5. How do I find why a Podman container exited?

Run podman ps -a for Exited status and the code in parentheses. Use podman inspect --format '{{.State.ExitCode}}' CONTAINER for the numeric code, podman logs CONTAINER for application output, and podman events --filter container=CONTAINER --stream=false for start, died, kill, and stop transitions.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)