When a Docker container is configured with a restart policy like restart: always or restart: unless-stopped, any internal crash causes Docker to immediately reboot the container. The result is an endless loop: the container starts, crashes within seconds, and restarts repeatedly.
Fixing a restarting container requires retrieving its exit code and inspecting logs from the exact moment of failure.
Quick Answer
Stop the container loop first so you can inspect it cleanly:
docker stop <container_name_or_id>
Check the exit code and whether it was terminated by Linux Out of Memory (OOM):
docker inspect <container_name_or_id> --format='ExitCode: {{.State.ExitCode}} | OOMKilled: {{.State.OOMKilled}} | Error: {{.State.Error}}'
Inspect the last 100 log lines to read the application crash trace:
docker logs --tail 100 <container_name_or_id>
Common solutions include supplying missing environment variables, raising container memory limits, or correcting the ENTRYPOINT/CMD directive so PID 1 runs in the foreground.
Symptoms
- Running
docker psshowsRestarting (1) 4 seconds agoorUp Less than a second. - In Kubernetes environments, the pod enters
CrashLoopBackOff. - High CPU consumption on the Docker host as containers cycle through startup initialization over and over.
- Associated microservices cannot connect to the container’s exposed ports.
Common Causes & Exit Codes
Understanding the container’s exit code reveals the exact category of failure:
| Exit Code | Meaning | Common Cause |
|---|---|---|
| 0 | Success / Normal exit | The main process finished its job or went into background mode (daemonized), leaving nothing for Docker to keep alive. |
| 1 | Application error | Uncaught exception in code, syntax error, missing environment variable, or configuration file not found. |
| 127 | Command not found | The executable specified in ENTRYPOINT or CMD does not exist inside the container image or isn’t in $PATH. |
| 137 | Terminated by SIGKILL | Linux Out of Memory (OOMKilled: true), or container was killed manually with docker kill. |
| 139 | Segmentation fault | Memory corruption or binary incompatibility between the container image architecture and host processor. |
Before You Start
- When a container restarts repeatedly, its stdout logs can flood the host disk if log rotation is not configured in Docker daemon.
- Temporarily pause or stop the container before making edits to
docker-compose.ymlor your startup scripts. - Ensure you have access to the original
Dockerfileordocker runparameters.
Step 1 — Check the Container’s Exit Status
Run docker ps -a to view the container status and exit code:
docker ps -a --filter "status=restarting" --filter "status=exited"
To extract the exact internal state using docker inspect:
docker inspect api-backend --format='Status: {{.State.Status}} | ExitCode: {{.State.ExitCode}} | OOMKilled: {{.State.OOMKilled}}'
What the Output Tells You
Status: restarting | ExitCode: 137 | OOMKilled: true
- If
OOMKilled: true: The container exceeded its memory limit or exhausted host RAM. You must increase the memory allocation. - If
ExitCode: 1: The application encountered an error and exited. Inspect the logs next. - If
ExitCode: 0: The process exited cleanly because it was not configured to stay in the foreground.
Step 2 — Read the Application Crash Logs
View the container logs to find the exact stack trace or error message:
docker logs --tail 100 --timestamps api-backend
Example 1: Database Connection Failure (Exit Code 1)
2026-09-18T14:22:01.129841Z [FATAL] Database connection failed: dial tcp 10.0.1.4:5432: connect: connection refused
2026-09-18T14:22:01.130104Z [FATAL] Exiting application with code 1
- Fix: The container depends on a PostgreSQL database that is either still starting up, on an incorrect Docker network, or blocked by a host firewall.
Example 2: Missing Environment Variable
2026-09-18T14:23:10.450122Z Error: Required environment variable JWT_SECRET is not set.
- Fix: Provide the missing variable in your
.envordocker-compose.ymlfile.
Step 3 — Investigate Out of Memory (Exit Code 137)
If OOMKilled was true, check the host kernel logs to see how much memory the container attempted to use when the kernel terminated it:
dmesg -T | grep -i -E "oom|killed process"
Sample Output
[Fri Sep 18 14:25:10 2026] Task in /docker/9a3f2b... killed as a result of limit of /docker/9a3f2b...
[Fri Sep 18 14:25:10 2026] Memory cgroup out of memory: Killed process 28190 (node) total-vm:2104500kB, anon-rss:512240kB
How to Fix Memory Limits
If your container was launched with strict memory limits (such as --memory="512m"), increase the limit in docker-compose.yml:
services:
api-backend:
image: node-api:latest
deploy:
resources:
limits:
memory: 1024M
reservations:
memory: 512M
If the host itself has zero free memory, add swap space or upgrade your server instance.
Step 4 — Fix Backgrounding Process Issues (Exit Code 0)
A container stays running only as long as its primary process (PID 1) remains active in the foreground. If the process detaches or daemonizes, the container stops immediately.
Incorrect Configuration
Using daemon flags inside CMD causes instant container exit:
# WRONG: nginx runs in background, container exits immediately with code 0
CMD ["nginx"]
Correct Configuration
Force services to run in the foreground:
# CORRECT: keeps process in foreground as PID 1
CMD ["nginx", "-g", "daemon off;"]
For Apache:
CMD ["apache2ctl", "-D", "FOREGROUND"]
Step 5 — Debug the Container Interactively
If the container crashes too quickly to view logs or you need to inspect files inside the image, override the ENTRYPOINT with an interactive shell:
docker run --rm -it --entrypoint /bin/sh api-backend:latest
- For Debian/Ubuntu-based images with Bash:
docker run --rm -it --entrypoint /bin/bash api-backend:latest
Once inside the interactive shell:
- Verify configuration files:
cat /etc/app/config.json - Test network connectivity:
curl -v http://database:5432ornc -zv database 5432 - Execute the startup script manually line-by-line to see where it breaks.
Step 6 — Restart and Verify Container Health
Once you have updated the configuration or resource limits, restart the container:
docker compose up -d api-backend
Monitor its status continuously for 30 seconds to ensure it does not restart:
watch -n 1 'docker ps | grep api-backend'
Healthy Target State
CONTAINER ID IMAGE COMMAND STATUS PORTS
9a3f2b4c1e8d node-api:latest "docker-entrypoint.s…" Up 2 minutes 0.0.0.0:3000->3000/tcp
Ensure the status says Up X minutes rather than Restarting (1).
Common Mistakes
- Leaving
restart: alwayson broken containers: Causes thousands of failed container restarts per hour, which can generate gigabytes of log files and wear out host disk I/O. - Hardcoding
localhostfor container connections: Inside a Docker container,localhostrefers to the container itself, not the host machine or neighboring containers. Use service names (likedborredis) within a shared Docker network. - Missing directory permissions on volume mounts: Mounting a host directory like
/srv/datato a container with root ownership when the container runs as an unprivileged user (likenodeorwww-data).
Prevention Checklist
- Implement Docker container health checks (
HEALTHCHECK) to distinguish running containers from truly healthy ones. - Always set reasonable memory limits and memory reservations in
docker-compose.yml. - Configure JSON file log rotation (
max-size: "50m",max-file: "3") in/etc/docker/daemon.json. - Ensure entrypoint scripts end with
exec "$@"to pass PID 1 signals (likeSIGTERM) cleanly to the application. - Consult our Docker support and DevOps services engineers for multi-container orchestration audits.
Quick Reference Commands
| Action | Command |
|---|---|
| Stop restarting loop | docker stop <container> |
| Check exit code and OOM status | docker inspect <container> --format='{{.State.ExitCode}} | OOM:{{.State.OOMKilled}}' |
| View last 100 lines of logs | docker logs --tail 100 --timestamps <container> |
| Check host OOM events | dmesg -T | grep -i oom |
| Override entrypoint with shell | docker run --rm -it --entrypoint /bin/sh <image> |
| Real-time container resource usage | docker stats |
Frequently Asked Questions
Why does a container restart immediately after starting?
A container restarts when its main process exits. If restart: always is configured, Docker restarts it immediately. Common causes include an unhandled exception during initialization, missing configuration or environment variables, or a command that exited immediately because it did not run in the foreground.
What is the difference between exit code 137 and exit code 1?
Exit code 1 is an application-level failure (the code crashed with an error or unhandled exception). Exit code 137 means the process was terminated by SIGKILL (signal 9, 128 + 9 = 137), almost always caused by the Linux kernel Out-of-Memory killer because the container exceeded its RAM limit.
Can a Docker container restart cause host server high load?
Yes. If an intensive application (like a Java JVM or large Node.js service) crashes and restarts every 2 seconds, the continuous initialization, compilation, and disk read cycles can drive host CPU and disk load averages to 100%.
How do I stop all restarting containers on a host at once?
Run:
docker ps -q --filter "status=restarting" | xargs -r docker stop
How does ServerCare360 assist with container stability?
Our Docker support and Kubernetes support engineers audit Dockerfiles, optimize multi-stage builds, configure cgroup resource boundaries, implement production monitoring in Grafana, and design zero-downtime rolling deployment pipelines.