{"record":{"id":"66edd70f07e04b1b","repo":"docker/cli","slug":"s-w-66edd7","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/stack/deploy_composefile.go","lineNumber":308,"sourceCode":"\t\t\t\tEncodedRegistryAuth: encodedAuth,\n\t\t\t\tQueryRegistry:       queryRegistry,\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to create service %s: %w\", name, err)\n\t\t\t}\n\n\t\t\tserviceIDs = append(serviceIDs, response.ID)\n\t\t}\n\t}\n\n\treturn serviceIDs, nil\n}\n\nfunc waitOnServices(ctx context.Context, dockerCli command.Cli, serviceIDs []string, quiet bool) error {\n\tvar errs []error\n\tfor _, serviceID := range serviceIDs {\n\t\tif err := service.WaitOnService(ctx, dockerCli, serviceID, quiet); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"%s: %w\", serviceID, err))\n\t\t}\n\t}\n\treturn errors.Join(errs...)\n}\n","sourceCodeStart":290,"sourceCodeEnd":313,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/stack/deploy_composefile.go#L290-L313","documentation":"Raised by waitOnServices (deploy path, --detach=false) when service.WaitOnService returns an error for a given serviceID. The %s is the service ID and %w wraps the underlying error (context cancellation, task failure reaching converge state, RPC error). Multiple per-service errors are joined with errors.Join.","triggerScenarios":"Running `docker stack deploy` without --detach (so waitOnServices runs at deploy_composefile.go:308), and one or more services fail to converge within the task wait, or the wait is interrupted. Each failing serviceID yields its own wrapped error.","commonSituations":"A service's tasks failing to start (bad image, crash loop, failed healthcheck); context deadline/cancellation (e.g. Ctrl-C during converge); manager communication error during the wait; tasks rejected by placement constraints.","solutions":["Inspect the failing service's tasks: `docker service ps <serviceID>` and look at the error column.","Resolve the underlying task failure (fix image, healthcheck, constraints, mounts).","Redeploy; transient failures clear once the root cause is fixed.","If you don't need to block on convergence, deploy with --detach and poll separately."],"exampleFix":"// before: blocking deploy surfaces per-service converge failure\n// after: diagnose the failing service's tasks\ndocker service ps --no-trunc <serviceID>\n# read the ERROR column, fix root cause, then re-run:\ndocker stack deploy -c compose.yml mystack","handlingStrategy":"retry","validationCode":"// Pre-check likely convergence blockers: image pullability, healthcheck validity, constraints\nfor _, svc := range services {\n    if svc.Healthcheck != nil && len(svc.Healthcheck.Test) == 0 {\n        return fmt.Errorf(\"service %s healthcheck misconfigured\", svc.Name)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := stackDeploy(ctx, cli, opts, cfg) // --detach=false\nif err != nil {\n    var joinErr interface{ Unwrap() []error }\n    if errors.As(err, &joinErr) {\n        for _, e := range joinErr.Unwrap() {\n            // each is \"<serviceID>: <cause>\"; inspect tasks for that serviceID\n        }\n    }\n}","preventionTips":["Validate healthchecks and images before deploying.","Watch `docker service ps` during convergence to catch failures early.","Use --detach and external convergence monitoring for CI determinism."],"tags":["docker","stack","deploy","service","wait","converge","swarm"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}