KhueApps
Home/DevOps/Fixing “OCI runtime exec failed: container not running” in Docker

Fixing “OCI runtime exec failed: container not running” in Docker

Last updated: October 06, 2025

Overview

When docker exec returns:

OCI runtime exec failed: container not running

it means Docker found the container object, but its state is not running (it may be exited, dead, created, or paused). The fix is to start or unpause the container and resolve why it stopped.

This guide shows a quick triage, a minimal repro, common causes, and durable fixes.

Quickstart (fast triage)

  1. List container state:
    • docker ps -a --filter name=<name-or-id>
  2. If status is Exited/Dead/Created, inspect details:
    • docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}' <name>
    • docker logs --tail=100 <name>
  3. If paused, unpause:
    • docker unpause <name>
  4. If exited and safe to restart:
    • docker start <name>
    • Then retry: docker exec -it <name> sh
  5. If it immediately exits again, fix the root cause (bad command, PID 1 daemonizes, OOM, permission, missing env) and redeploy.

Minimal working example (repro and fix)

This shows why docker exec fails if the container exits immediately, and how to keep it running.

Failing container (exits instantly)

Dockerfile:

# Dockerfile
FROM alpine:3.19
CMD ["echo", "container exits immediately"]

Build and run:

docker build -t oci-exec-demo .
docker run -d --name demo oci-exec-demo

# Container exits right away; exec fails
docker exec -it demo sh    # -> OCI runtime exec failed: container not running

Check status and logs:

docker ps -a --filter name=demo
docker logs demo

Fixed container (kept alive)

Override the command to keep PID 1 running:

docker rm -f demo

docker run -d --name demo oci-exec-demo sh -c "sleep infinity"

docker exec -it demo sh    # works

Alternatively, design the image so the main process stays in the foreground (preferred for services).

Step-by-step diagnosis

  1. Confirm the container name/ID

    • Mistyped names yield “No such container,” not this error. Ensure you target the correct container: docker ps -a | grep <pattern>
  2. Check container state

    • docker inspect -f '{{json .State}}' <name> | jq .
    • Key fields: .Status (running/exited/paused/dead), .ExitCode, .Error, .OOMKilled, .Health.Status (if defined).
  3. Read recent logs

    • docker logs --tail=200 <name>
    • Look for command-not-found, permission denied, address in use, config errors, stack traces.
  4. Unpause if needed

    • Error can appear if paused: docker ps --filter status=paused
    • docker unpause <name>
  5. Start or restart

    • docker start <name> to start a stopped container.
    • docker restart <name> if it’s wedged or after config fix.
    • If the container exits immediately after start, fix the entrypoint/CMD or image config.
  6. Verify PID 1 stays in foreground

    • Many daemons fork to background by default; PID 1 exits and the container stops.
    • Use foreground flags (examples):
      • nginx: nginx -g 'daemon off;'
      • redis: redis-server --daemonize no
      • httpd: httpd -DFOREGROUND
  7. Check resources and limits

    • OOM: .State.OOMKilled == true -> increase memory or fix memory leak.
    • CPU/ulimits: relax constraints or tune app.
  8. Adjust restart policy (optional)

    • docker update --restart unless-stopped <name>
    • Ensures the container restarts, but still fix the root cause to avoid crash loops.

Common causes and fixes

SymptomLikely causeHow to fix
Exited (0) instantlyCMD finished (no long-running process)Run the app in foreground; for debugging, use sleep infinity or a shell as PID 1.
Exited (>0) with errorBad command, missing binary, config errorFix entrypoint/CMD, install deps, correct config/env vars.
OOMKilled trueMemory limit too low or leakIncrease --memory, tune app, reduce concurrency.
PausedManual pause or Docker Desktopdocker unpause <name>.
DeadEngine crash or corrupted containerdocker rm -f <name> and recreate from image.
Healthcheck unhealthy + restartsOrchestrator restarts containerFix app health, not just restart policy.
Daemonized servicePID 1 exits after forkingUse no-daemon/foreground flags or wrapper.

Compose and Swarm notes

  • Compose status and logs:
docker compose ps
docker compose logs --tail=200 <service>
  • Start or recreate:
docker compose up -d <service>
# If config changed:
docker compose up -d --build <service>
  • Exec into a Compose service only when running:
docker compose exec <service> sh
  • Swarm services: docker exec works on container tasks on the local node only. Find the running task first:
docker service ps <service> --no-trunc
# Then docker exec into the specific running task container ID on that node

Pitfalls

  • Using docker run --rm for one-shot jobs: the container is removed on exit; you cannot exec into it later.
  • Misleading success: docker start returns immediately even if the container exits right after. Always check docker ps and docker logs.
  • Entrypoint scripts with set -e and unhandled errors cause early exit; add logging and explicit error handling.
  • Overriding CMD at run time can unintentionally replace a proper foreground process; verify the final command with docker inspect -f '{{.Path}} {{.Args}}' <name>.

Performance notes

  • Avoid tight loops of docker exec in automation; each exec spawns a process in the container. Prefer APIs, health endpoints, or a dedicated debug sidecar.
  • Use docker logs --tail=N instead of full logs to reduce I/O when diagnosing restarts.
  • Crash loops waste resources; apply backoff and fix the cause. Combine --restart with proper observability to avoid masking issues.
  • Keep containers small and deterministic. Minimal base images reduce startup failures and attack surface.

FAQ

  • Why did my container exit immediately?

    • Its main process (PID 1) finished. Ensure your service runs in the foreground, or keep it alive during debugging.
  • Does docker exec start a container?

    • No. It only enters an already running container. Use docker start first.
  • How do I keep a container alive just for debugging?

    • Run with a long sleep or a shell as PID 1: docker run -d <image> sh -c "sleep infinity".
  • I’m on Windows/Mac with Docker Desktop. Anything special?

    • The steps are the same. Watch for paused or stopped containers after Desktop restarts.
  • Why do I still get the error after docker restart?

    • The container crashes on startup. Inspect logs and entrypoint, fix the error, then redeploy.

Series: Docker

DevOps