dependency failed to start: container ... is unhealthy means a service you listed under depends_on with condition: service_healthy failed its healthcheck, so Compose would not start the service that waits for it. The problem is in the dependency or in its healthcheck, not in the service that waits for it.

Read the dependency's health log with docker inspect: it lists every check with its exit code and output. Fix whatever makes the check fail, or fix the check if it tests the wrong thing.

The error

PS> docker compose up
...
 Container fix8-cli-h5-db-1 Started
 Container fix8-cli-h5-db-1 Waiting
 Container fix8-cli-h5-db-1 Error dependency db failed to start
dependency failed to start: container fix8-cli-h5-db-1 is unhealthy

The file:

name: fix8-cli-h5
services:
  db:
    image: alpine
    command: ["sleep", "infinity"]
    healthcheck:
      test: ["CMD", "test", "-f", "/tmp/ready"]
      interval: 2s
      timeout: 2s
      retries: 2
  app:
    image: alpine
    command: ["echo", "app started"]
    depends_on:
      db:
        condition: service_healthy

Why it happens

A healthcheck is a command the engine runs inside the container at every interval. After retries failures in a row the container is marked unhealthy. With condition: service_healthy, Compose waits for healthy, and when the dependency turns unhealthy instead it gives up and does not start app at all. In the test the check looked for /tmp/ready, which the db container never created.

The health log shows it plainly: two checks, both with exit code 1 and no output, and a failing streak of 2, which equals retries:

PS> docker inspect --format "{{json .State.Health}}" fix8-cli-h5-db-1
{"Status":"unhealthy","FailingStreak":2,"Log":[{"Start":"2026-11-06T07:24:27.617767635Z","End":"2026-11-06T07:24:27.644431332Z","ExitCode":1,"Output":""},{"Start":"2026-11-06T07:24:29.644088097Z","End":"2026-11-06T07:24:29.668009652Z","ExitCode":1,"Output":""}]}

The Output field is empty here because test -f prints nothing; a check command that prints an error shows it there. The timestamps end in Z, so they are UTC.

The fix

Make the dependency pass its check; here the command creates the file the check expects:

    command: ["sh", "-c", "touch /tmp/ready; sleep infinity"]
PS> docker compose -f compose.fixed.yaml up --abort-on-container-exit --exit-code-from app
 Container fix8-cli-h5-db-1 Waiting
 Container fix8-cli-h5-db-1 Healthy
 Container fix8-cli-h5-app-1 Starting
app-1  | app started

The dependency turned Healthy and app started, where the broken run had shown Error dependency db failed to start at the same step. The outputs are trimmed to the relevant lines. If the service is slow to start rather than broken, raise retries or the interval instead, so the check is not given up too early.

How it was reproduced

Docker Desktop on Windows 11, engine 29.9.2, Docker Compose v5.6.1, Windows PowerShell 5.1, the cached alpine:latest image for both services. The healthcheck tested for a file the container never created, with a two-second interval and two retries; the health log shows the two failed checks two seconds apart. The project name fix8-cli-h5 is the test's own.

Frequently asked

How do I see why a Docker container is unhealthy?
Run docker inspect --format "{{json .State.Health}}" <container>. The Log array lists each check with its exit code and output, and FailingStreak shows how many failed in a row.
Why does docker compose not start my service when the dependency is unhealthy?
With depends_on and condition: service_healthy, Compose waits for the dependency to be healthy. When it turns unhealthy instead, Compose stops and reports dependency failed to start.
How do I give a slow service more time to become healthy?
Raise retries or interval in its healthcheck so it is not marked unhealthy before it has finished starting.

More decoded errors in the Fixes category.