Docker Container Exited with Code 1: Diagnose and Fix

A container that stops immediately with exit code 1 and empty logs usually fails before the app can write anything. Extract the command and environment, replay it in the foreground, and correct the Docker definition on Linux or Windows.

Rao Aadil, India 8 min read

Confirm the symptom: the container exited (1) and logs are silent

Containers that exit with code 1 show up in docker ps -a as Exited (1) or a restart loop. Don't assume the app wrote nothing; check a few basics first. docker ps -a lists all containers, including stopped ones, and works the same on Linux, PowerShell, and cmd:

docker ps -a

The command is identical on Windows PowerShell and cmd.

Next, pull the exact exit code and any error the Docker daemon recorded:

docker inspect --format '{{.State.ExitCode}} {{.State.Error}}' <container>

PowerShell accepts single quotes; cmd requires double quotes:

docker inspect --format "{{.State.ExitCode}} {{.State.Error}}" <container>

You'll see either 1 and an empty Error, or 1 with OCI runtime create failed. A plain 1 means the process returned 1 and the daemon reported nothing extra.

Then check the last 200 lines of logs:

docker logs --tail 200 <container>

No output? The process may have failed before writing to stdout or stderr, or it wrote to a file inside the container that was lost when the container stopped. For containers that ran for a while and still show no logs, see the separate guidance on empty logs for running containers.

Doing this with brynko devOps Agent

“The service dies under load and nothing in the application log explains it, because the application never got to write one.”

Exit 137 means the kernel killed it, almost always the memory limit. It checks the configured limit against usage history and tells you what the ceiling is and what the job needs.

It reads the real state of the server before it says anything, shows you the exact command, and waits for your approval. Windows and Linux, over the SSH access you already have.

Download for WindowsSee what else it does

Extract the command, entrypoint, environment, and working directory that just failed

The container's configuration survives exit. Use docker inspect to read the merged runtime definition, not just the image default. On Linux:

docker inspect <container> | jq '.[0].Config'

On Windows PowerShell, jq isn't installed by default; use ConvertFrom-Json:

docker inspect <container> | ConvertFrom-Json | Select-Object -ExpandProperty Config

In cmd, you can output the raw JSON and look through it, but PowerShell is the practical choice.

Config contains Config.Cmd, Config.Entrypoint, Config.Env, Config.WorkingDir, and Config.Volumes. A container exiting with code 1 often has one of these mismatched with the developer's intention. Look for:

  • Cmd and Entrypoint that use relative paths or depend on a shell to expand variables.
  • Env entries that reference variables not set in the container's environment.
  • A WorkingDir that does not exist inside the image.
  • Volumes pointing to paths that are not mounted or have wrong permissions.

Compare these values against the Dockerfile, Compose file, or docker run command that created the container. The difference is usually the cause.

Replay the failed command in the foreground to surface the hidden error

Still nothing? Run the container again attached to its standard streams. docker start -a starts a stopped container and attaches in one step:

docker start -a <container>

Works on Linux and Windows hosts. If the container exits again, the fatal message lands on your terminal. Some applications only write their fatal message when a TTY is present; -a usually provides stdout and stderr, but add -i if you need an interactive session.

If the container won't start or you need to change the entrypoint temporarily, run the same image with the same environment and mounts, but override the entrypoint. On Linux:

docker run --rm -it --entrypoint /bin/sh <image>

Then set the same environment and working directory, and run the original command manually. Windows containers don't have /bin/sh; use PowerShell or cmd:

docker run --rm -it --entrypoint powershell <image>

or

docker run --rm -it --entrypoint cmd <image>

Inside that shell, navigate to the original WorkingDir and execute the exact Cmd or Entrypoint from docker inspect. The error that was silent before shows up because the process is attached to your console and stderr is captured.

Diagnose the cause from the replay output

Exit code 1 is a generic application-level failure, not a Docker daemon error. The daemon successfully started and stopped the container; the process inside returned 1. Once the replay surfaces the error message, match it to a known cause.

Common causes:

  • Missing file or directory: the command tries to open a config file, data directory, or mount point that is absent.
  • Syntax error in a config file: the app parses a YAML, JSON, or INI file and exits before logging.
  • Unset required environment variable: the app tries to read os.Getenv("DATABASE_URL") and fails fast.
  • Bind mount permission denied: on Linux, the container user cannot read or write the host path; on Windows, the path may not be shared with Docker Desktop or may use a drive letter that is not mapped.
  • Port already in use: the app binds to a port that is occupied on the host or inside the container network; the error may be address already in use.
  • Missing dependency: the command references a binary or library that is not in the image, sometimes reported as executable file not found in $PATH (which often means a missing shared library or shebang interpreter).
  • OCI runtime create failed: this is a Docker runtime error that occurs before the container process starts, often due to a bad mount, missing volume, or Windows path mismatch.

A healthcheck that fails while the main process runs points to the healthcheck definition, not the entrypoint. The separate guides on bind mount permission denied and healthcheck failures cover those in detail; the same diagnostic method applies.

Fix the container definition in the Dockerfile, Compose file, or run command

With the specific error in hand, fix the source definition so the next container starts correctly.

For CMD and ENTRYPOINT, use absolute paths and the exec form. In a Dockerfile:

CMD ["/app/server", "--config", "/etc/app/config.yaml"]

not

CMD ./server --config config.yaml

The exec form does not invoke a shell, which preserves signals and avoids shell interpretation surprises. On Windows images, the path must use backslashes or forward slashes consistently; the exec form in PowerShell can be ["C:\\app\\server.exe", "--config", "C:\\app\\config.yaml"] or forward slashes ["C:/app/server.exe", ...].

Set required environment variables explicitly in the Compose file:

environment:
  DATABASE_URL: "postgres://db:5432/app"

Alternatively, use env_file:. After starting, inspect the running container to confirm the variables are present. docker inspect <container> shows Config.Env on both Linux and Windows; check that the values match.

Bind mount permissions are a frequent cause on Linux. If the container user cannot write to the mounted directory, change the ownership or mode on the host path:

sudo chown -R 1000:1000 /opt/myapp/data
sudo chmod -R 775 /opt/myapp/data

On Windows, ensure the folder exists and is shared in Docker Desktop settings. The path inside the container must be a valid Windows path; in Compose, use a volume like C:\opt\myapp\data:C:\app\data with appropriate escaping in YAML.

Before restarting the stack, validate the merged Compose file:

docker compose config

Run it from the directory containing compose.yaml or docker-compose.yml, on Linux and Windows; it prints the final configuration and catches syntax errors or missing variables.

Prevent recurrence with healthchecks, restart policies, and local testing

After the fix, add safeguards so the next failure doesn't disappear silently.

A HEALTHCHECK in the Dockerfile or a healthcheck: block in Compose should exercise the real application endpoint, not just return 200 from a static root. For example:

HEALTHCHECK CMD curl -f http://localhost/health || exit 1

or in Compose:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost/health"]
  interval: 30s
  timeout: 5s
  retries: 3

On Windows images, use PowerShell for the healthcheck:

HEALTHCHECK CMD powershell -command "try { Invoke-WebRequest http://localhost/health -UseBasicParsing } catch { exit 1 }"

Choose a restart policy that keeps the container visible without a tight loop. restart: unless-stopped restarts after a crash but stops when you explicitly stop it; restart: on-failure with a max retry count works for development. Avoid restart: always on a container that exits immediately with code 1, since it hides the failure and fills logs.

Use a logging driver that persists and rotates logs. The default json-file driver can set max-size and max-file in /etc/docker/daemon.json on Linux or Docker Desktop settings on Windows, so logs from the failed attempt survive even after the container is removed.

Get help from the Docker AI agent for repeated code 1 failures

If you have multiple registered servers, the Docker AI agent can find which container exited with code 1. It lists stopped containers across servers, reads the exit code, command, and environment, and can start a stopped container attached to capture output, or run a read-only diagnostic with approval. Ask it "which container is exiting with code 1 on this server" or "why does this container keep restarting"; the agent inspects the relevant containers, shows logs and stats, and offers to restart a service after confirmation. Once you've fixed the Dockerfile or Compose file yourself, the agent can bring the stack up in /opt/myapp on Linux or C:\opt\myapp on Windows. It can't rewrite your Dockerfile or Compose file; it surfaces the error and helps you run the fixed definition.

Related reading

Fix a Docker container that exits with code 1

Use the Docker AI agent to find exited containers across your servers, see the command and environment that failed, and restart the fixed stack with confirmation.

An AI teammate that builds, runs, fixes, deploys and operates your software, on your machine and on your servers. It reads the real state of your systems, shows you every command before it runs, and never touches production without your approval.

Works with Docker Docker Compose nginx IIS Tomcat MySQL / MariaDB PostgreSQL Redis Linux servers Windows servers AWS Jenkins Let's Encrypt Node.js Python Java .NET Go PHP
  • Every change asks first, and shows you the exact command or diff before it runs.
  • File edits are snapshotted and reversible. Deleted folders are archived, not removed.
  • Private key material never reaches the model, under any setting.
brynko devOps Agent
Docker

the checkout container keeps restarting

read container state checked health check listed ports

It restarts every 40 seconds, and it is the health check failing rather than the app. The check calls /healthz on port 8080, but the app is listening on 3000, so it never passes and Docker keeps killing it.

fix it

one line in compose restarted watched 5 minutes

Done. I corrected the health check port and restarted the service. It has stayed up since, and the check is passing.

Fixed · container healthy

Free download for Windows. 300 free credits on signup, no card, no subscription.

Questions

Common questions

Why does my Docker container exit immediately with code 1 and no logs?
The container started, but the process inside returned a generic failure before writing to stdout or stderr. Common reasons are a missing file, unset environment variable, or a command that cannot execute. Re-running the container in the foreground usually reveals the error.
How do I see the command that actually ran inside a container that already exited?
Use `docker inspect <container>` and look at `Config.Cmd`, `Config.Entrypoint`, and `Config.Env`. On Linux you can pipe to `jq`, and on Windows PowerShell use `ConvertFrom-Json` to read the same fields.
Can I re-run a stopped container in the foreground to see the error?
Yes, `docker start -a <container>` starts the existing container and attaches to its stdout and stderr. If the container is too broken, use `docker run --rm -it --entrypoint /bin/sh <image>` on Linux or `--entrypoint powershell` on Windows to replay the command manually.
Does exit code 1 always mean my application crashed? What are common causes?
Exit code 1 is a generic application-level failure, not a Docker daemon error. Common causes include missing files, config syntax errors, unset required environment variables, bind mount permission denied, port already in use, and missing dependencies.
How do I inspect environment variables of a stopped container?
`docker inspect <container>` includes `Config.Env` with all environment variables set at container creation. On Linux you can run `docker inspect <container> | jq '.[0].Config.Env'`; on Windows PowerShell, `docker inspect <container> | ConvertFrom-Json | Select-Object -ExpandProperty Config | Select-Object -ExpandProperty Env`.
What should I change if the container works on my machine but exits code 1 on the server?
Compare the image, environment variables, and bind mounts between the two hosts. On the server, check for missing files, different absolute paths, or permissions on mounted volumes. Also verify that the exact same image tag is deployed and that the environment variables are passed in the server's Compose or run command.

Keep reading