docker/cli · error

failed to update config

Error message

failed to update config %s: %w

What it means

Raised by createConfigs when a swarm config already exists (found via ConfigInspect) but the subsequent ConfigUpdate API call fails. The wrapped %w error carries the underlying daemon error. Configs are the mutable-file equivalent of secrets and follow the same inspect-then-update lifecycle during redeploy.

Solutions

  1. Read the wrapped error for the daemon-specific reason.
  2. Retry the deploy to clear transient version conflicts.
  3. Remove and recreate the config: `docker config rm <name>` then redeploy.
  4. Serialize concurrent deploys targeting the same stack's configs.

Example fix

// before: redeploy fails on version conflict
// after: remove stale config and redeploy
docker config rm mystack_myconfig
docker stack deploy -c compose.yml mystack
Defensive patterns

Strategy: retry

Try / catch

// Retry on transient config update failures (e.g. version conflict)
for attempt := 0; attempt < 3; attempt++ {
    err := stackDeploy(ctx, cli, opts, cfg)
    if err == nil { return nil }
    if !strings.Contains(err.Error(), "failed to update config") {
        return err
    }
}
return errors.New("config update failed after retries")

Prevention

When it happens

Trigger: Redeploying a stack where a config in compose.yml was changed, causing ConfigUpdate at deploy_composefile.go:149 to fail. Triggers on version conflicts, immutable-field changes, or concurrent modification between the Inspect and Update.

Common situations: Concurrent stack deploys racing on the same config; manager node unhealthy; changing a field the daemon treats as immutable on update; config removed out-of-band mid-deploy.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/dab5c59d5b0ba418. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/stack/deploy_composefile.go:154

		}
	}
	return nil
}

func createConfigs(ctx context.Context, dockerCLI command.Cli, configs []swarm.ConfigSpec) error {
	apiClient := dockerCLI.Client()

	for _, configSpec := range configs {
		res, err := apiClient.ConfigInspect(ctx, configSpec.Name, client.ConfigInspectOptions{})
		switch {
		case err == nil:
			// config already exists, then we update that
			_, err := apiClient.ConfigUpdate(ctx, res.Config.ID, client.ConfigUpdateOptions{
				Version: res.Config.Meta.Version,
				Spec:    configSpec,
			})
			if err != nil {
				return fmt.Errorf("failed to update config %s: %w", configSpec.Name, err)
			}
		case errdefs.IsNotFound(err):
			// config does not exist, then we create a new one.
			_, _ = fmt.Fprintln(dockerCLI.Out(), "Creating config", configSpec.Name)
			_, err := apiClient.ConfigCreate(ctx, client.ConfigCreateOptions{
				Spec: configSpec,
			})
			if err != nil {
				return fmt.Errorf("failed to create config %s: %w", configSpec.Name, err)
			}
		default:
			return err
		}
	}
	return nil
}

func createNetworks(ctx context.Context, dockerCLI command.Cli, namespace convert.Namespace, networks map[string]client.NetworkCreateOptions) error {

View on GitHub (pinned to 4f84911bfe)