nektos/act · error
service container failed to start
Error message
service container failed to start
What it means
A service container did not report a 'healthy' state in time. act polls the container's Docker healthcheck with an exponential backoff (delay doubling up to 10s, capped at ~30 iterations starting from HealthStarting); if the final observed state is anything other than healthy (still starting, unhealthy, or no healthcheck defined), this error is returned after waitForServiceContainer completes.
Source
Thrown at pkg/runner/run_context.go:606
sctx, cancel := context.WithTimeout(ctx, time.Minute*5)
defer cancel()
health := container.HealthStarting
delay := time.Second
for i := 0; ; i++ {
health = c.GetHealth(sctx)
if health != container.HealthStarting || i > 30 {
break
}
time.Sleep(delay)
delay *= 2
if delay > 10*time.Second {
delay = 10 * time.Second
}
}
if health == container.HealthHealthy {
return nil
}
return fmt.Errorf("service container failed to start")
}
}
func (rc *RunContext) waitForServiceContainers() common.Executor {
return func(ctx context.Context) error {
execs := []common.Executor{}
for _, c := range rc.ServiceContainers {
execs = append(execs, rc.waitForServiceContainer(c))
}
return common.NewParallelExecutor(len(execs), execs...)(ctx)
}
}
func (rc *RunContext) stopServiceContainers() common.Executor {
return func(ctx context.Context) error {
execs := []common.Executor{}
for _, c := range rc.ServiceContainers {
execs = append(execs, c.Remove().Finally(c.Close()))View on GitHub (pinned to 4f41128141)
Solutions
- Run `docker ps` and `docker inspect --format '{{json .State.Health}}' <service-container>` to see the healthcheck status and its last output/error.
- Fix whatever makes the healthcheck fail: correct credentials in the healthcheck command, exposed port, or required env vars in the service definition.
- Use an official image variant that ships a working HEALTHCHECK (e.g. postgres with POSTGRES_* env set properly).
- If the service is just slow, reduce startup work (disable fsync for test DBs) or increase act's available time rather than switching to a healthcheck-less image.
- If you control the image, add a Docker HEALTHCHECK so the state can transition to healthy.
Example fix
# before
services:
postgres:
image: postgres:16
env: { POSTGRES_PASSWORD: '' } # healthcheck pg_isready fails
# after
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: test
POSTGRES_USER: test
POSTGRES_DB: test Defensive patterns
Strategy: retry
Validate before calling
# Pre-flight: does the image have a healthcheck?
docker inspect --format '{{.Config.Healthcheck}}' mydb:latest 2>/dev/null | grep -q CMD && echo ok || echo 'no healthcheck — service will never be healthy' Try / catch
if err := rc.waitForServiceContainers()(ctx); err != nil {
log.WithError(err).Warn("service not healthy; retrying once after daemon warmup")
time.Sleep(30 * time.Second)
err = rc.waitForServiceContainers()(ctx)
} Prevention
- Prefer official images with built-in HEALTHCHECKs.
- Set correct env (credentials, ports) the healthcheck depends on.
- Warm slow images once (docker pull) before act runs.
When it happens
Trigger: The service image has no HEALTHCHECK and never transitions past HealthStarting, the container's healthcheck command keeps failing (DB not ready, wrong credentials, missing dependency), the image reports 'unhealthy', or the ~minutes-long polling budget expires before the service becomes ready.
Common situations: Database service containers (postgres/mysql/redis) whose healthcheck uses wrong credentials or a long startup time; custom Docker images without a HEALTHCHECK instruction; slow machines (CI runners, cold Docker daemon) where startup exceeds the wait budget; service misconfigured via options/env so the process inside crashes at boot.
Related errors
- failed to handle service %s credentials: %w
- failed to parse service %s ports: %w
- --pid: invalid PID mode
- --uts: invalid UTS mode
- --userns: invalid USER mode
AI-assisted analysis of nektos/act@4f41128141 (2026-08-15).
Data as JSON: /api/errors/b39921ede688a51a.
Report an issue: GitHub.