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

  1. Read the wrapped error to get the daemon's specific rejection reason.
  2. If 'update out of sequence' / version conflict, retry the deploy.
  3. Verify referenced secrets/configs/networks exist and are correctly named.
  4. Check node availability/constraints with `docker node ls` if scheduling is the issue.
  5. 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

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


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)