Docker Exit Code Explainer

Paste the number from docker ps -a. The one people arrive with is 137, and it is two entirely different problems wearing the same number.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Explain. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

The one everybody arrives with

SIGKILL, from either the OOM killer or a stop timeout, and they need different fixes

137

A clean stop

SIGTERM, handled properly. This is what a correct shutdown looks like

143

Found but not executable

Three likely causes, and none of them is a missing file

126

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Treating every 137 as an out-of-memory problem

    It is SIGKILL, which is also what docker stop sends after the grace period. Raising the memory limit for a shutdown problem changes nothing.

    Instead:Check docker inspect --format '{{.State.OOMKilled}}' first. False means the process is ignoring SIGTERM.

  2. Looking in the container logs after a 125

    No container was created, so there are no logs. The error is on the output of the run command itself.

    Instead:Read the command's own output. It names the flag or the conflict.

  3. Reading 126 as a missing file

    The file was found. It could not be executed, which is usually a missing execute bit, Windows line endings, or a shebang naming an interpreter the image does not have.

    Instead:chmod +x in the Dockerfile, check the line endings, and confirm the interpreter exists.

Docker owns four ranges and the program owns the rest

125, 126, 127 and everything above 128 come from Docker or the kernel. Anything else was chosen by the program, and Docker knows nothing about what it means.

137 is SIGKILL, and there are two ways to get one

Either the kernel's OOM killer ended the process because the container hit its memory limit, or docker stop timed out after the grace period and Docker escalated from SIGTERM. Those need completely different fixes. docker inspect --format '{{.State.OOMKilled}}' is the deciding field: true means memory, false means your process ignored SIGTERM, which usually means a shell at PID 1.

125, 126 and 127 are three different failures that look alike

125 means the docker command itself failed and no container was created, so the error is on the command's own output. 126 means the file was found and could not be executed: not executable, CRLF line endings, or a shebang pointing at something absent. 127 means the file is not there at all, which on a distroless base is usually a shell that was never in the image.

Anything above 128 is 128 plus a signal

So 143 is SIGTERM, which is a clean stop and the code you want to see. 139 is SIGSEGV, which in a container is often an architecture mismatch or a glibc binary on an Alpine base. 130 is Ctrl-C.

Exit 1 carries no information

It is a generic non-zero chosen by the program. Docker records it and knows nothing more, so the logs are the only source.

An OOM kill leaves no trace in the application's log

The kernel ends the process immediately: no signal handler, no flush, no final line. The log stops mid-sentence, which is itself the clue.

A clean exit stops an on-failure policy

Which is why a container with on-failure that exits zero is not restarted, and why a wrapper script swallowing a failure turns a restart loop into silence.

More docker tools

Docker Container Image Reference Parser Is that a registry or a Docker Hub user? Dockerfile Linter What this image will do to you later docker run to Kubernetes YAML And the flags that have no equivalent Docker Compose to Kubernetes And why depends_on has no equivalent Docker Logging Driver Generator json-file never rotates Dockerfile Non-Root USER Generator Numeric, or Kubernetes rejects it Docker OCI Image Labels Generator One of them actually does something Docker Hub Pull Rate Limit Calculator Counted per IP, not per person Docker Registry Storage Calculator Deleting a tag frees nothing Docker Build Context Analyzer All of it uploads before anything runs Docker Compose to docker run Converter Names stop resolving Docker Compose Version Migrator version: is obsolete now Docker Compose Network and Port Viewer Everything reaches everything Docker Command Explainer Which flags hand over the host Docker BuildKit Cache Mount Generator apt deletes the cache you just mounted Docker BuildKit Secret Mount Generator ARG is in docker history forever Docker .dockerignore Pattern Tester *.log does not match logs/app.log Docker Image Manifest Viewer unknown/unknown is not broken Docker Image Config Viewer Anyone who can pull can read your Env Docker Registry Token Decoder Check the scope before the credentials Docker HEALTHCHECK Generator Docker does nothing when it fails Docker Network Subnet Calculator 31 networks, then it stops Docker History Analyzer The rm did not save anything Docker Run to Compose Converter Some flags have no equivalent Docker CMD and ENTRYPOINT Tester Why docker stop takes ten seconds Docker Port Mapping Tester -p reaches past your firewall Docker -v to --mount Converter -v invents missing directories Docker Restart Policy Simulator The backoff resets after ten seconds Docker CPU Limit Converter --cpu-shares limits nothing Docker Memory Limit Calculator -m 512m allows a gigabyte Docker Compose Interpolation Tester An unset variable is an empty string Docker Environment Variable Precedence Tester Your shell does not reach the container Docker Compose Override Merge Previewer An override can add a port, never remove one Dockerfile Multi-Stage Build Analyzer Which stages reach the image Dockerignore Validator It is not .gitignore

Elsewhere on the site