How to fix Container exited with code 128: invalid exit argument in Docker

DockerINTERMEDIATEMEDIUMUpdated May 28, 2026· 393 views

Docker exit code 128 almost always comes from a failed git operation (auth, host-key, or directory-ownership) during a build, or from the OCI runtime failing to create the container. Here is how to diagnose and fix it.

Quick fix

Fixes Container exited with code 128: invalid exit argument

# Application output (if any)
docker logs <container_name_or_id>

# Exit code and any runtime-level error message
docker inspect <container_name_or_id> --format='{{.State.ExitCode}} {{.State.Error}}'
  1. Read the actual error above the 128 line
  2. Fix git authentication in the build (private repos)
  3. Trust the git host key
  4. Resolve git 'dubious ownership' on mounted source
docker — error
# Application output (if any)
docker logs <container_name_or_id>
# Exit code and any runtime-level error message
docker inspect <container_name_or_id> --format='{{.State.ExitCode}} {{.State.Error}}'
Container exited with code 128: invalid exit argument

What this error means

In the Docker world, "exit code 128" is reported in two distinct situations, and it is important not to confuse them. **1. A command inside a build or container returned 128.** This is by far the most common case, and the command is nearly always `git`. Git itself uses exit code 128 as its generic "fatal" exit status, so any fatal git error — authentication failure, "Host key verification failed", "repository not found", or "detected dubious ownership in repository" — surfaces as `exit status 128` (often shown as `The command '/bin/sh -c git clone ...' returned a non-zero code: 128` during `docker build`). The number does not tell you which git problem occurred; you have to read the log line above it. **2. The OCI runtime (runc/crun via containerd) failed to create or start the container.** Here Docker reports something like `OCI runtime create failed: ...` and the container never runs your process. This is a configuration or environment problem — a bad entrypoint path, a missing binary, a permission problem, or a runtime/containerd issue — not a signal and not your application's own exit code. What 128 does *not* mean for Docker: it is not a "signal exit." Signal-terminated processes report `128 + n` (e.g. 137 for SIGKILL, 143 for SIGTERM), so 128 itself is not in that family. And while bash returns 128 for an out-of-range/non-integer argument to its `exit` builtin, that is a niche scripting edge case and is rarely the real reason a Docker build or container reports 128 — don't go looking there first.

Typical symptoms

  • docker build fails with The command '/bin/sh -c git clone ...' returned a non-zero code: 128
  • Build log shows fatal: Authentication failed or fatal: Could not read from remote repository just before exit status 128
  • git clone fails with Host key verification failed inside the build
  • fatal: detected dubious ownership in repository at '/app' followed by exit status 128
  • Docker reports OCI runtime create failed and the container never starts
  • Container shows Exited (128) in docker ps -a with no application output
  • docker-compose up or CI pipeline fails at a git-related build step with exit status 128

Common causes

  1. Git authentication failed during the build: SSH keys or credentials were not available inside the build (most common with private repos).
  2. SSH host key was not trusted, so git clone aborted with 'Host key verification failed'.
  3. Git refused to operate because of directory ownership mismatch ('detected dubious ownership'), common with bind-mounted source as root.
  4. The remote repository or branch/ref does not exist or the URL is wrong ('repository not found').
  5. The OCI runtime could not create the container: bad/missing entrypoint binary, wrong path, or permission problem.
  6. A runtime/containerd/runc problem on the host (corrupted state or version mismatch) causing 'OCI runtime create failed'.
  7. A script in the image called bash's `exit` with a non-integer or out-of-range argument (rare; only relevant if you control such a script).

How to fix "Container exited with code 128: invalid exit argument"

1Read the actual error above the 128 line

Exit code 128 is generic — the real cause is in the line just before it. Don't guess; read the log.

For a build failure, re-read the failing step's output (look for fatal: from git). For a stopped container:

bash
# Application output (if any)
docker logs <container_name_or_id>

# Exit code and any runtime-level error message
docker inspect <container_name_or_id> --format='{{.State.ExitCode}} {{.State.Error}}'

Key strings to look for: Authentication failed, Host key verification failed, repository not found, detected dubious ownership, or OCI runtime create failed. Each points to a different fix below.

2Fix git authentication in the build (private repos)

If the log shows a git auth failure, supply credentials to the build without baking secrets into image layers.

Preferred: BuildKit SSH forwarding — the key is never written into the image.

dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache git openssh-client
# Trust GitHub's host key (avoids 'Host key verification failed')
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone git@github.com:user/repo.git

Build with your SSH agent forwarded in:

bash
DOCKER_BUILDKIT=1 docker build --ssh default .

Alternative for HTTPS: a build secret (also keeps the token out of the final image, unlike an ARG):

dockerfile
# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=gh_token \
    git clone https://x-access-token:$(cat /run/secrets/gh_token)@github.com/user/repo.git
bash
DOCKER_BUILDKIT=1 docker build --secret id=gh_token,env=GITHUB_TOKEN .

Avoid passing the token via a plain ARG/ENV — it gets stored in image history and leaks the credential.

3Trust the git host key

If the error is Host key verification failed, the build environment has never connected to the host and won't accept an unknown key non-interactively. Add the host key explicitly:

dockerfile
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

Do not disable host-key checking (e.g. StrictHostKeyChecking=no or UserKnownHostsFile=/dev/null) — that defeats the protection against man-in-the-middle attacks. ssh-keyscan pinning the known host is the safe equivalent. For extra assurance, verify the scanned fingerprint against the provider's published keys.

4Resolve git 'dubious ownership' on mounted source

If the log shows fatal: detected dubious ownership in repository at '/app', git is refusing to operate because the working tree is owned by a different user than the one running git (common when source is bind-mounted and the container runs as root).

Mark the specific path as safe:

bash
git config --global --add safe.directory /app

Or in a Dockerfile, scoped to the known path:

dockerfile
RUN git config --global --add safe.directory /app

Prefer naming the exact directory. Using the wildcard safe.directory '*' disables this safety check everywhere and should only be a last resort in a fully trusted, single-purpose image.

5Verify the repository, branch, and URL exist

If git reports repository not found or a missing ref, 128 is just git's fatal status for a bad target. Confirm the clone target outside Docker first:

bash
git ls-remote git@github.com:user/repo.git
# or for HTTPS
git ls-remote https://github.com/user/repo.git

Check for typos in the URL, a private repo accessed without credentials, or a --branch/ref that no longer exists.

6Diagnose OCI runtime 'create failed' errors

If Docker reports OCI runtime create failed rather than a git error, the runtime couldn't start your process. Common root causes: an entrypoint/command that doesn't exist or isn't executable, a wrong path, or a missing interpreter (e.g. a #!/bin/bash script in an image that only has /bin/sh).

Inspect what the image is trying to run, then test it interactively:

bash
docker inspect <image> --format='ENTRYPOINT={{.Config.Entrypoint}} CMD={{.Config.Cmd}}'

# Override the entrypoint to get a shell and probe the environment
docker run -it --entrypoint /bin/sh <image>
ls -la /app/entrypoint.sh        # exists and executable (x bit)?
head -1 /app/entrypoint.sh       # correct shebang for an interpreter present in the image?

Fix the path/permissions (chmod +x), correct the shebang, or install the missing interpreter.

7Rule out a host-level runtime/containerd problem

If the image is fine but OCI runtime create failed persists across containers, check the daemon and runtime on the host:

bash
sudo journalctl -u docker.service -n 50
sudo journalctl -u containerd.service -n 50

docker version
containerd --version
runc --version

A restart often clears transient runtime state:

bash
sudo systemctl restart docker

If versions are mismatched, update via your package manager (e.g. sudo apt-get update && sudo apt-get install --only-upgrade containerd.io docker-ce).

Note: docker system prune deletes all stopped containers, unused networks, dangling images, and the build cache — it is not a targeted fix and can remove data you still need. Only run it after confirming you don't need those resources, and avoid prune --volumes unless you are certain the data is disposable.

Advanced notes

128 is not a signal exit. Signal-terminated containers report 128 + n (e.g. 130 = SIGINT, 137 = SIGKILL/OOM, 139 = SIGSEGV, 143 = SIGTERM). A bare 128 is *not* in that family — it is overwhelmingly git's generic fatal status or an OCI runtime create failure. Don't apply the 128+n reasoning to a plain 128.

Why git returns 128: git uses exit code 128 as its catch-all "fatal" status (die() internally). That is why authentication, host-key, ownership, and "not found" errors all collapse to the same number — the human-readable fatal: line is the real diagnostic, not the code.

BuildKit SSH agent setup: for --mount=type=ssh, your agent must hold the key on the host before building:

bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
DOCKER_BUILDKIT=1 docker build --ssh default .

The key stays on the host and is forwarded only for that RUN step, so it never lands in an image layer.

Don't weaken transport security to silence 128: disabling StrictHostKeyChecking or embedding tokens via ARG/ENV will make the error go away but introduces a MITM or credential-leak risk. Use ssh-keyscan to pin known hosts and BuildKit --ssh/--secret to keep credentials out of the image.

Systemd ordering for network-dependent containers: if a container relies on a network mount at boot, order the unit after the mount is ready:

ini
# /etc/systemd/system/docker-myapp.service
[Unit]
After=remote-fs.target docker.service
Requires=docker.service

Frequently asked questions

What does "Container exited with code 128: invalid exit argument" mean?
In the Docker world, "exit code 128" is reported in two distinct situations, and it is important not to confuse them. 1. A command inside a build or container returned 128.
How do I fix "Container exited with code 128: invalid exit argument"?
Docker exit code 128 almost always comes from a failed git operation (auth, host-key, or directory-ownership) during a build, or from the OCI runtime failing to create the container. Here is how to diagnose and fix it.
What causes "Container exited with code 128: invalid exit argument"?
Git authentication failed during the build: SSH keys or credentials were not available inside the build (most common with private repos). SSH host key was not trusted, so git clone aborted with 'Host key verification failed'. Git refused to operate because of directory ownership mismatch ('detected dubious ownership'), common with bind-mounted source as root.
Is the "Container exited with code 128: invalid exit argument" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading