Skip to content
DevOps AI ToolKit
Newsletter
All guides
Docker with AI By James Joyner IV · · 9 min read

Docker Error Guide: 'OCI runtime create failed: runc create failed' Container Start Failures

Fix 'OCI runtime create failed: runc create failed' by reading the runc error suffix — missing binary, permission denied, no such file, or bad mount.

  • #docker
  • #troubleshooting
  • #errors
  • #runtime

Exact Error Message

docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: ...

The message almost always carries a meaningful suffix that names the real sub-case:

... unable to start container process: exec: "myapp": executable file not found in $PATH: unknown

... unable to start container process: exec: "/entrypoint.sh": permission denied: unknown

... unable to start container process: error mounting "/data" to rootfs at "/data": no such file or directory: unknown

What It Means

OCI runtime create failed comes from the low-level runtime (runc, the default OCI runtime) at the moment it tries to materialize your container from the image plus your run-time configuration. The image was pulled successfully and the daemon accepted the request — but when runc set up the namespaces, mounts, and then attempted to launch the very first process inside the new container, something failed.

This is a generic wrapper. On its own, “runc create failed: unable to start container process” tells you only where it broke (container creation), not why. The text after the final colon is the actual diagnosis. Reading that suffix is the entire job.

A useful mental model: the error is a stack of nested layers — daemon, shim, OCI runtime, runc, and finally the container process itself. Each layer prefixes its own “failed to…” text, which is why the message looks so long and repetitive. Everything before the last colon is just each layer reporting that the layer below it failed. Train your eye to skip straight to the end of the line; the leading clauses rarely change and rarely matter. The categories below cover essentially every real-world tail you will encounter.

Common Causes

The suffix maps to a small set of distinct root causes:

  • exec: "<x>": executable file not found in $PATH — your ENTRYPOINT/CMD names a binary that is not installed in the image or not on PATH. See the dedicated guide below.
  • exec: "<x>": permission denied — the target exists but is not executable (missing +x bit), or it’s a script whose interpreter isn’t usable.
  • exec: "<x>": no such file or directory — the binary exists but its interpreter/loader is missing (e.g. a dynamically-linked binary in a scratch/musl image), or a shebang points at a non-existent shell.
  • error mounting "..." to rootfs ... — a bind-mount source path doesn’t exist on the host, or a volume target conflicts with the image filesystem. See the invalid-mount guide.
  • cgroup / runc environment issuescgroup v1/v2 mismatch, a missing runc binary, or an incompatible runtime version.
  • seccomp / AppArmor — a security profile blocks a syscall needed during container start.

How to Reproduce the Error

Trivially reproducible per sub-case. The cleanest is the missing-binary form:

docker run --rm alpine /does-not-exist
# ... OCI runtime create failed: runc create failed: unable to start container
#     process: exec: "/does-not-exist": executable file not found in $PATH: unknown

The permission-denied form:

printf '#!/bin/sh\necho hi\n' > entry.sh   # note: no chmod +x
docker run --rm -v "$PWD/entry.sh:/entry.sh" alpine /entry.sh
# ... unable to start container process: exec: "/entry.sh": permission denied: unknown

Diagnostic Commands

Read the full error, then inspect the container’s configured entrypoint and the image itself.

# Re-run and capture the COMPLETE error suffix — the part after the last colon
docker run --rm <image> 2>&1 | tail -3

# What entrypoint/cmd was the container configured with?
docker inspect <container_or_id> --format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}'

# For a container that failed to start, inspect its create-time config and error
docker inspect <container> --format '{{.State.Error}}'

# Confirm the runtime itself is healthy and which runtime is default
docker info --format '{{.DefaultRuntime}}'
runc --version

# Host-level evidence for cgroup / OOM / seccomp during start
journalctl -u docker --no-pager -n 30
dmesg | tail -20

A failed start leaves the container in Created/Exited with the error preserved:

$ docker inspect web --format '{{.State.Error}}'
failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "node": executable file not found in $PATH: unknown

Step-by-Step Resolution

  1. Read the suffix and classify. Grab everything after the final : — that single phrase decides which path you take below.

  2. executable file not found in $PATH → the binary isn’t in the image. Drop into a shell and check:

    docker run --rm --entrypoint sh -it <image> -c 'command -v myapp; echo $PATH'

    Install the binary or fix the path. Full walkthrough in the executable-file-not-found guide.

  3. permission denied → the entrypoint isn’t executable. Fix it in the Dockerfile:

    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]

    For a bind-mounted script, chmod +x it on the host before mounting.

  4. no such file or directory (binary exists) → the dynamic loader or interpreter is missing. For Go/Rust on scratch, build a static binary (CGO_ENABLED=0). For a script, ensure the shebang interpreter exists (/bin/sh exists in alpine; /bin/bash may not).

  5. error mounting ... to rootfs → a bind-mount source doesn’t exist on the host. Verify the host path, then re-run. See the invalid-mount guide. Quick check:

    ls -ld /data    # the -v source must exist on the host
  6. cgroup / runtime issues → if the suffix mentions cgroups or runc itself, confirm the runtime is installed and the cgroup driver matches the daemon’s:

    docker info --format '{{.CgroupDriver}} {{.CgroupVersion}}'
    sudo systemctl restart docker

How to Prevent the Issue

  • Use the JSON-array (exec) form for ENTRYPOINT/CMD and reference binaries by absolute path so the runtime resolves them deterministically.
  • RUN chmod +x every script you COPY in, and verify the shebang interpreter exists in your base image.
  • Build static binaries (CGO_ENABLED=0) when targeting scratch or distroless images to avoid missing-loader failures.
  • Validate bind-mount source paths in your deploy tooling before docker run.
  • Pin a known-good runc/containerd version and keep the daemon’s cgroup driver consistent across the fleet.
  • Add a smoke test to CI that actually docker runs the freshly built image with its real entrypoint; most of these suffixes surface immediately on first start, so catching them in the pipeline keeps them out of production.
  • When you customize seccomp or AppArmor profiles, test the container start with the profile applied — a profile that blocks a startup syscall produces a runc-create failure that looks unrelated to security at first glance.
Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.