docker/compose · error
service %q didn't complete successfully: exit %d
Error message
service %q didn't complete successfully: exit %d
What it means
During convergence, Compose waits for depends_on dependencies; when a dependency's container exits non-zero while a `service_completed_successfully` condition (or --wait with exit handling) is evaluated, the wait fails with 'service %q didn't complete successfully: exit %d' and the dependent service is never started (unless the dependency is marked optional).
Source
Thrown at pkg/compose/convergence.go:248
if code == 0 {
s.events.On(containerEvents(waitingFor, exited)...)
return nil
}
messageSuffix := fmt.Sprintf("%q didn't complete successfully: exit %d", dep, code)
if !config.Required {
// optional -> mark as skipped & don't propagate error
s.events.On(containerReasonEvents(waitingFor, skippedEvent,
fmt.Sprintf("optional dependency %s", messageSuffix))...)
logrus.Warnf("optional dependency %s", messageSuffix)
return nil
}
msg := fmt.Sprintf("service %s", messageSuffix)
s.events.On(containerEvents(waitingFor, func(s string) api.Resource {
return errorEventf(s, "service %s", messageSuffix)
})...)
return errors.New(msg)
}
default:
logrus.Warnf("unsupported depends_on condition: %s", config.Condition)
return nil
}
}
})
}
err := eg.Wait()
if errors.Is(err, context.DeadlineExceeded) {
return fmt.Errorf("timeout waiting for dependencies")
}
return err
}
func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceDependency, project *types.Project) (bool, error) {
if dependencyConfig.Condition == types.ServiceConditionStarted {
// already managed by InDependencyOrderView on GitHub (pinned to ddc4b044b6)
Solutions
- Run `docker compose logs <dependency>` to see why it exited non-zero and fix the container itself (missing env var, bad command, missing file)
- If failure is acceptable, mark the dependency `required: false` so Compose skips instead of aborting
- Re-run the one-shot manually (`docker compose run --rm <dep>`) to iterate on the failure without full up
- Verify the image/entrypoint referenced actually exists (exit 127/125 style failures)
Example fix
# before
services:
app:
depends_on:
migrate:
condition: service_completed_successfully
migrate:
command: ./migrate.sh # exits 1
# after
services:
app:
depends_on:
migrate:
condition: service_completed_successfully
required: false
migrate:
command: sh -c "./migrate.sh || true" Defensive patterns
Strategy: try-catch
Validate before calling
# pre-check the dependency container exits 0 before running dependents docker compose run --rm migrate || echo 'migrate failed — fix before up'
Try / catch
# in scripts, tolerate a known-failing optional dependency by marking it required: false in the file, # and branch on the exit status of `docker compose up --wait`: if ! docker compose up --wait; then docker compose logs migrate; exit 1; fi
Prevention
- Make one-shot dependencies idempotent and loud about their own failures (clear logs, non-zero exit)
- Use required: false for dependencies whose failure should not block startup
- Smoke-test migration containers standalone in CI before wiring depends_on
When it happens
Trigger: `docker compose up` where a service has depends_on: {condition: service_completed_successfully} and that dependency container exits with a non-zero code (e.g. a migrations one-shot container failing), or `up --wait` on a stack where a dependency exits badly.
Common situations: Init/migration containers (flyway migrate, django migrate) failing their command; flaky health-dependent one-shots; a wrong entrypoint or missing env var in the dependency causing exit 1; marking the dependency required when it is optional.
Related errors
- %s is missing dependency %s
- healthcheck.start_interval requires healthcheck.start_period
- cannot share volume with service %s: container missing
- cannot share network namespace with service %s: container mi
- cannot share IPC namespace with service %s: container missin
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/c72881bf6419c70a.
Report an issue: GitHub.