docker/cli · error
failed to update service
Error message
failed to update service %s: %w
What it means
Raised by deployServices when updating an existing service and ServiceUpdate fails. The wrapped %w carries the daemon error. This is the redeploy path (the service already exists in the stack namespace) and the update carries the new spec, registry auth, and image-resolution options.
Solutions
- Read the wrapped error to get the daemon's specific rejection reason.
- If 'update out of sequence' / version conflict, retry the deploy.
- Verify referenced secrets/configs/networks exist and are correctly named.
- Check node availability/constraints with `docker node ls` if scheduling is the issue.
- Validate the image reference and registry credentials.
Example fix
// before: referencing a non-existent secret in update
services:
web:
secrets:
- missing_secret
// after: ensure the secret is declared
secrets:
missing_secret:
file: ./secret.txt
services:
web:
secrets:
- missing_secret Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate service spec fields that commonly cause ServiceUpdate rejection
for _, svc := range desiredServices {
if svc.Image == "" { return fmt.Errorf("service %s has no image", svc.Name) }
for _, s := range svc.Secrets { if !secretExists(s) { return fmt.Errorf("service %s refs missing secret %s", svc.Name, s) } }
for _, c := range svc.Configs { if !configExists(c) { return fmt.Errorf("service %s refs missing config %s", svc.Name, c) } }
for _, n := range svc.Networks { if !networkExists(n) { return fmt.Errorf("service %s refs missing network %s", svc.Name, n) } }
} Try / catch
err := stackDeploy(ctx, cli, opts, cfg)
if err != nil && strings.Contains(err.Error(), "failed to update service") {
// re-inspect, surface wrapped reason; retry only on version conflicts
var se interface{ Unwrap() error }
if errors.As(err, &se) {
if strings.Contains(se.Unwrap().Error(), "update out of sequence") { /* retry */ }
}
} Prevention
- Validate referenced secrets/configs/networks exist before deploy.
- Ensure images are pushable and registry auth is provided.
- Serialize deploys to avoid version conflicts on update.
When it happens
Trigger: Redeploying a stack where one or more services already exist; ServiceUpdate at deploy_composefile.go:272 returns an error (version conflict, invalid spec, resource constraint, scheduling failure).
Common situations: Updating a service with an invalid image reference or mount; concurrent deploys causing version conflicts; daemon-side rejection (e.g. constraint that no node satisfies); referencing a secret/config that doesn't exist yet; changing a field the daemon forbids on update.
Related errors
- failed to create service
- %s: %w
- this node is not a swarm manager. Use "docker swarm init"…
- failed to update secret
- failed to update config
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/e828697d8e5e6c21.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/stack/deploy_composefile.go:274
default:
if image == svc.Spec.Labels[convert.LabelImage] {
// image has not changed; update the serviceSpec with the
// existing information that was set by QueryRegistry on the
// previous deploy. Otherwise this will trigger an incorrect
// service update.
serviceSpec.TaskTemplate.ContainerSpec.Image = svc.Spec.TaskTemplate.ContainerSpec.Image
}
}
// Stack deploy does not have a `--force` option. Preserve existing
// ForceUpdate value so that tasks are not re-deployed if not updated.
// TODO move this to API client?
serviceSpec.TaskTemplate.ForceUpdate = svc.Spec.TaskTemplate.ForceUpdate
updateOpts.Spec = serviceSpec
response, err := apiClient.ServiceUpdate(ctx, svc.ID, updateOpts)
if err != nil {
return nil, fmt.Errorf("failed to update service %s: %w", name, err)
}
for _, warning := range response.Warnings {
_, _ = fmt.Fprintln(dockerCLI.Err(), warning)
}
serviceIDs = append(serviceIDs, svc.ID)
} else {
_, _ = fmt.Fprintln(out, "Creating service", name)
// query registry if flag disabling it was not set
queryRegistry := resolveImage == resolveImageAlways || resolveImage == resolveImageChanged
response, err := apiClient.ServiceCreate(ctx, client.ServiceCreateOptions{
Spec: serviceSpec,
EncodedRegistryAuth: encodedAuth,
QueryRegistry: queryRegistry,
})View on GitHub (pinned to 4f84911bfe)