Exit code 130 indicates that a Docker container was terminated by SIGINT (signal 2), typically triggered by pressing Ctrl+C. The exit code follows the Unix convention of 128 + signal number, so 128 + 2 = 130. This is normal behavior when manually stopping a container, not an error.
Exit code 130 is a standard Unix/Linux exit code that indicates a process was terminated by SIGINT (signal interrupt). SIGINT is signal number 2, and by Unix convention, when a process is killed by a signal, its exit code is calculated as 128 + signal number. Therefore, 128 + 2 = 130. When you press Ctrl+C on an attached Docker container, the terminal sends SIGINT to the container's main process (PID 1). If the process handles this signal and terminates gracefully, the container exits with code 130. This is expected behavior, not an error. However, there's an important nuance: a process running as PID 1 inside a container is treated specially by Linux. It ignores any signal with the default action unless the process is explicitly coded to handle it. This means some containers won't respond to Ctrl+C at all unless properly configured for signal handling.
Exit code 130 is not an error - it's the standard Unix way of indicating that a process was interrupted by SIGINT (Ctrl+C). If you intentionally stopped the container with Ctrl+C, this exit code is correct and expected.
# Check container exit code
docker inspect <container> --format='{{.State.ExitCode}}'
# Output: 130The container exited cleanly in response to your interrupt signal.
If you don't want to accidentally stop containers with Ctrl+C, run them in detached mode:
# Run in detached mode (background)
docker run -d --name mycontainer myimage
# View logs without attaching
docker logs -f mycontainer
# Stop gracefully when needed
docker stop mycontainerWith detached mode, Ctrl+C only stops the log following, not the container itself.
If your container doesn't respond to Ctrl+C properly, use the --init flag to add a minimal init process that handles signals correctly:
docker run --init -it myimageThe init process (tini) runs as PID 1 and properly forwards signals to your application, ensuring clean shutdown behavior.
For graceful shutdown, your application should handle SIGINT and SIGTERM:
# Python example
import signal
import sys
def signal_handler(signum, frame):
print("Received signal, shutting down gracefully...")
# Cleanup code here
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)// Node.js example
process.on('SIGINT', () => {
console.log('Received SIGINT, shutting down...');
// Cleanup code here
process.exit(0);
});The exec form of CMD/ENTRYPOINT ensures your process receives signals directly:
# Exec form (recommended) - signals go directly to your app
CMD ["node", "server.js"]
# Shell form (not recommended) - signals go to /bin/sh
CMD node server.jsWith shell form, /bin/sh runs as PID 1 and may not forward signals to your application.
If your CI/CD pipeline treats exit code 130 as a failure, you may need to handle it explicitly:
# Bash script example
docker run mycontainer || exit_code=$?
if [ "$exit_code" -eq 130 ]; then
echo "Container was interrupted (expected)"
exit 0
fi
exit $exit_codeOr in your CI configuration, mark 130 as an acceptable exit code for cancelled jobs.
Signal propagation in docker-compose: When you press Ctrl+C on docker-compose up, compose catches SIGINT and sends SIGTERM (not SIGINT) to containers by default. The containers may exit with code 0 or 143 (128+15) rather than 130, depending on configuration.
PID 1 and signal handling: Linux treats PID 1 specially - it won't receive signals with default handlers. This is why many containers use init systems like tini or dumb-init. Without proper signal handling, Ctrl+C might appear to do nothing.
Difference between SIGINT and SIGTERM:
- SIGINT (2) - Interrupt signal, typically from Ctrl+C, exit code 130
- SIGTERM (15) - Termination signal, from docker stop, exit code 143
Graceful vs immediate shutdown: docker stop sends SIGTERM first, waits (default 10 seconds), then sends SIGKILL. Ctrl+C sends SIGINT immediately. Design your application to handle both gracefully.
Kubernetes considerations: When a pod is terminated, Kubernetes sends SIGTERM. Exit code 130 in Kubernetes usually indicates manual intervention (kubectl delete) or preStop hooks that triggered SIGINT.
dockerfile parse error line 5: unknown instruction: RRUN
How to fix 'unknown instruction' Dockerfile parse error in Docker
Error response from daemon: manifest for nginx:nonexistent not found: manifest unknown: manifest unknown
How to fix 'manifest for image:tag not found' in Docker
Error response from daemon: invalid reference format: repository name must be lowercase
How to fix 'repository name must be lowercase' in Docker
Error response from daemon: No such image
How to fix 'No such image' in Docker
Error response from daemon: Container is not running
How to fix 'Container is not running' when using docker exec