A container keeps restarting — exit code 137, 139 or 1
The exit code says how the process died, and each one points somewhere different.
What you see
docker ps shows the container restarting repeatedly, or Kubernetes reports CrashLoopBackOff. The application logs may show nothing at all, because it was killed rather than exiting.
What is actually wrong
137 is SIGKILL, nearly always the memory limit. 143 is SIGTERM, a normal stop. 139 is a segmentation fault. 1 is the application exiting with an error, and its own logs will say why.
Codes and articles
Fixes (3)
Establish whether the limit is too low or the application leaks
137, or the state shows OOMKilled.
Confirm it was the memory limit rather than the host running out.
docker inspect --format '{{.State.OOMKilled}} {{.State.ExitCode}} {{.HostConfig.Memory}}' mycontainerdmesg -T | grep -i 'killed process' | tail
A container killed by its own cgroup limit and a container killed because the host ran out of memory look identical from the outside and need opposite fixes — one is a limit that is too low, the other is a host that is over-committed.
Watch its usage against the limit before changing anything.
docker stats --no-streamIf usage climbs steadily and never falls, it is a leak in the application and raising the limit only lengthens the interval between restarts.
For a JVM or Node application, make sure the runtime knows about the container limit — by default many runtimes read the host's total memory and size their heap for that.
docker run -e JAVA_OPTS='-XX:MaxRAMPercentage=75' myimageThis is a specific and extremely common cause: a JVM in a 512MB container sizing its heap against a 64GB host, then being killed the moment it grows into it.
Set a limit that reflects measured usage plus headroom.
docker update --memory 1g --memory-swap 1g mycontainerIn Kubernetes, set requests and limits together and keep them close for predictable scheduling.
kubectl describe pod mypod | grep -A5 -E 'Limits|Requests|Last State'
docker ps --format 'table {{.Names}}\t{{.Status}}'Investigate a segmentation fault in the container
139.
Check the architecture. An image built for arm64 running on x86 through emulation is a frequent cause.
docker image inspect myimage --format '{{.Architecture}} {{.Os}}'uname -m
Multi-architecture registries hand out whatever matches, and a pinned digest from another machine may not. This produces an immediate segfault with no useful log at all.
Check the base image's libc against the binary — a binary built against glibc will not run on an Alpine (musl) base.
Run the image interactively to see the failure directly.
docker run --rm -it --entrypoint /bin/sh myimageCheck for a seccomp or AppArmor profile blocking a system call, which can present as a crash.
docker run --rm --security-opt seccomp=unconfined myimageRunning unconfined is a diagnostic, not a fix. If it resolves the crash, the answer is a profile that permits the specific call, not permanently disabling the sandbox.
Rebuild the image on the target architecture, or pull the correct platform explicitly.
docker pull --platform linux/amd64 myimage
Read what the application said before it exited
Exit code 1 or another application-level code.
Read the logs from the previous run, not the current one — the container has already restarted.
docker logs --tail 100 mycontainerdocker logs --tail 100 --since 10m mycontainer
In Kubernetes, the previous container's logs are the ones that matter.
kubectl logs mypod --previous --tail=100kubectl describe pod mypod | tail -20
Without --previous you get the logs of the container that is currently starting, which has not failed yet. This is the single most useful flag for a CrashLoopBackOff and it is easy to miss.
Check the environment and configuration the container actually received — a missing variable is the usual cause.
docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' mycontainerCheck it can reach its dependencies. A database that is not up yet makes a container exit immediately and restart forever.
docker run --rm --network container:mycontainer nicolaka/netshoot nc -zv db 5432Override the entrypoint to get a shell inside the failing image and test by hand.
docker run --rm -it --entrypoint /bin/sh myimage
Related faults
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.