Exit Code 1 (General Error) in Docker & Kubernetes
Exit code 1 is the application's own generic failure. The process started and returned 1, or an uncaught exception was mapped to 1 by the runtime. It is not a signal and not 128+n, so the code alone says nothing; the first stack trace or validation error in the logs does.
Proof commands: confirm the exit status and the killer
Run these before changing anything. The first two identify what the runtime recorded; the third finds a kernel-level kill on the host. Replace the placeholder container ID, pod name or host path with your own.
Docker inspect
docker inspect <container_id> --format '{{.State.Status}} | ExitCode: {{.State.ExitCode}} | Error: {{.State.Error}}'Kubernetes state
kubectl get pod <pod_name> -o jsonpath='{range .status.containerStatuses[*]}{.name}{"\t"}{.lastState.terminated.reason}{"\tExit:"}{.lastState.terminated.exitCode}{"\n"}{end}'Application log
kubectl logs <pod_name> --previous --tail=200If .State.ExitCode is 1 and .State.OOMKilled is false, the kernel did not kill the process. That single fact separates this page from 137 (OOM/SIGKILL) and 139 (SIGSEGV). The next step is always the application's own first error line.
Three production root causes
The application ran and failed by its own rules. Look at docker logs or kubectl logs --previous for the first error, then check configuration, environment variables and mounted secrets. The status is intentionally generic and shared by many runtime failures.
1. Uncaught exception or failed assertion at startup
A Python traceback, a Java stack trace, a Node unhandled rejection or a failed config assertion typically ends the process with status 1. The container starts, reaches initialization and then calls exit(1). Search logs for the first traceback, not the last restart banner.
2. Missing or malformed environment variable or secret
Applications commonly validate DATABASE_URL, JWT_SECRET or API keys at boot. In Kubernetes a missing key in a Secret referenced with a non-optional env entry prevents the container from starting at all; a present but empty value passes the mount and fails application validation with exit 1. Compare kubectl exec env with the expected schema.
3. A shell wrapper propagated a child failure
With set -e, a failing command ends the script with that command's status, often 1. The real cause can be a curl health check, a migration command or a chown that fails because the user lacks permission. Run the entrypoint with sh -x locally or restore the failing command's stderr.
Copy-ready fixes for Docker Compose and Kubernetes
The two manifests set explicit memory limits and a termination grace period. Use them as a baseline, then adjust the values to the measured working set of the service.
docker-compose.yml
restart: on-failure:3 stops an immediate restart storm while preserving a few retries for a transient dependency. Do not use always here: a deterministic configuration error will restart forever and hide the first failure.
services:
app:
image: ghcr.io/acme/app:1.4.2
restart: on-failure:3
stop_grace_period: 20s
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
deployment.yaml
A crash loop with exit 1 is usually a configuration problem. Use kubectl logs --previous after the first restart, and check whether a Secret key exists before blaming the image. The liveness probe here prevents a half-started process from staying in the endpoint pool.
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 2
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
terminationGracePeriodSeconds: 30
containers:
- name: app
image: ghcr.io/acme/app:1.4.2
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "1000m"
memory: "512Mi"
env:
- name: LOG_LEVEL
value: "info"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
Frequently asked questions
How do I find the real reason for exit code 1?
Read the first error in docker logs or kubectl logs --previous, not the restart summary. Then verify the exact command and args the container runs, the environment variables and mounted secrets, and whether a shell wrapper used set -e. The exit code itself carries no more information.
Is exit code 1 the same as a container crash?
It is a clean process failure, not a kernel kill. The process ran and returned status 1. A crash caused by a signal would be 128+n, for example 137 for SIGKILL or 139 for SIGSEGV. Kubernetes may still label the pod CrashLoopBackOff because it restarts repeatedly.
Why does exit code 1 happen only in Kubernetes and not locally?
The usual differences are configuration: missing Secret or ConfigMap keys, a read-only root filesystem, a different user ID, or a DNS/service name that only exists inside the cluster. Compare the deployed env and mounts with the local compose file before changing application code.
Related exit codes, signals and network references
Follow the status you actually observed, then check the related port or calculator when the failure involves networking, exposure or firewall rules.
Reference basis: POSIX signal semantics (128 + n), Docker container exit status conventions, and Kubernetes container termination behaviour. Verify the exact behaviour against your runtime version before relying on it in an incident.
Last reviewed 2026-11-06 · All exit codes · Developer tools · Privacy