docker compose_error ai_generated true

dependency failed to start: container X is unhealthy

ID: docker/compose-depends-on-unhealthy

Also available as: JSON · Markdown
91%Fix Rate
91%Confidence
55Evidence
2022-01-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
27 active

Root Cause

The dependency service's healthcheck is failing or missing. Docker Compose v2 requires explicit healthchecks with 'depends_on: condition: service_healthy'. The most common cause is a missing or incorrect healthcheck definition.

generic

Workarounds

  1. 94% success Add a proper healthcheck to the dependency service
    In docker-compose.yml, add a healthcheck to the dependency. For PostgreSQL: healthcheck: { test: ['CMD-SHELL', 'pg_isready -U postgres'], interval: 5s, timeout: 5s, retries: 5 }. For MySQL: test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost']. For Redis: test: ['CMD', 'redis-cli', 'ping']. Then use depends_on: { db: { condition: service_healthy } }.

    Sources: https://docs.docker.com/compose/compose-file/05-services/#healthcheck

  2. 88% success Use wait-for-it.sh or dockerize as entrypoint wrapper
    Add wait-for-it.sh to your image and use as entrypoint: entrypoint: ['./wait-for-it.sh', 'db:5432', '--', 'node', 'server.js']. This polls the port until the dependency is accepting connections before starting the application.

    Sources: https://github.com/vishnubob/wait-for-it

  3. 90% success Ensure healthcheck tests actual readiness, not just port availability
    A TCP port check (nc -z) returns true before the database is ready to accept queries. Use service-specific readiness commands: pg_isready for PostgreSQL, mysqladmin ping for MySQL, redis-cli ping for Redis, curl localhost:9200/_cluster/health for Elasticsearch.

Dead Ends

Common approaches that don't work:

  1. Adding sleep commands in entrypoint scripts as a wait mechanism 75% fail

    Sleep-based waits are brittle and slow. They do not actually check service health and fail silently if the dependency takes longer than the sleep duration. Docker Compose v2 has native health-check-based waiting.

  2. Removing depends_on to let services start in parallel 88% fail

    Services start simultaneously with no ordering, causing 'connection refused' errors when the application starts before the database is ready. This makes the problem worse by trading a clear error for intermittent failures.

  3. Setting restart: always to keep retrying the dependent service 82% fail

    Creates an infinite restart loop: service fails → restarts → fails again. The dependency never becomes healthy just because the dependent restarts. Consumes resources and fills logs with repeated failures.

Error Chain

Frequently confused with: