{"record":{"id":"b39921ede688a51a","repo":"nektos/act","slug":"service-container-failed-to-start","errorCode":null,"errorMessage":"service container failed to start","messagePattern":"service container failed to start","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/runner/run_context.go","lineNumber":606,"sourceCode":"\t\tsctx, cancel := context.WithTimeout(ctx, time.Minute*5)\n\t\tdefer cancel()\n\t\thealth := container.HealthStarting\n\t\tdelay := time.Second\n\t\tfor i := 0; ; i++ {\n\t\t\thealth = c.GetHealth(sctx)\n\t\t\tif health != container.HealthStarting || i > 30 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttime.Sleep(delay)\n\t\t\tdelay *= 2\n\t\t\tif delay > 10*time.Second {\n\t\t\t\tdelay = 10 * time.Second\n\t\t\t}\n\t\t}\n\t\tif health == container.HealthHealthy {\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"service container failed to start\")\n\t}\n}\n\nfunc (rc *RunContext) waitForServiceContainers() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, rc.waitForServiceContainer(c))\n\t\t}\n\t\treturn common.NewParallelExecutor(len(execs), execs...)(ctx)\n\t}\n}\n\nfunc (rc *RunContext) stopServiceContainers() common.Executor {\n\treturn func(ctx context.Context) error {\n\t\texecs := []common.Executor{}\n\t\tfor _, c := range rc.ServiceContainers {\n\t\t\texecs = append(execs, c.Remove().Finally(c.Close()))","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/runner/run_context.go#L588-L624","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nservices:\n  postgres:\n    image: postgres:16\n    env: { POSTGRES_PASSWORD: '' }   # healthcheck pg_isready fails\n# after\nservices:\n  postgres:\n    image: postgres:16\n    env:\n      POSTGRES_PASSWORD: test\n      POSTGRES_USER: test\n      POSTGRES_DB: test","handlingStrategy":"retry","validationCode":"# Pre-flight: does the image have a healthcheck?\ndocker inspect --format '{{.Config.Healthcheck}}' mydb:latest 2>/dev/null | grep -q CMD && echo ok || echo 'no healthcheck — service will never be healthy'","typeGuard":null,"tryCatchPattern":"if err := rc.waitForServiceContainers()(ctx); err != nil {\n  log.WithError(err).Warn(\"service not healthy; retrying once after daemon warmup\")\n  time.Sleep(30 * time.Second)\n  err = rc.waitForServiceContainers()(ctx)\n}","preventionTips":["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."],"tags":["docker","services","healthcheck","timeout","containers"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}