docker/cli · error
failed to update secret
Error message
failed to update secret %s: %w
What it means
Raised by createSecrets when a swarm secret already exists (found via SecretInspect) but the subsequent SecretUpdate API call fails. The wrapped %w error carries the underlying daemon error (e.g. version conflict, immutable field change, permission).
Solutions
- Inspect the wrapped error message for the daemon's specific reason (e.g. 'update out of sequence').
- Retry the deploy; transient version conflicts often resolve on the next attempt.
- If the secret is truly malformed, remove it (`docker secret rm <name>`) and redeploy so it is recreated.
- Ensure no concurrent deploys are modifying the same stack's secrets.
Example fix
// before: concurrent deploys cause version conflict // after: serialize deploys or retry for i in 1 2 3; do docker stack deploy -c compose.yml mystack && break || sleep 2; done
Defensive patterns
Strategy: retry
Try / catch
// Retry on transient secret update failures (e.g. version conflict)
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
if err := stackDeploy(ctx, cli, opts, cfg); err == nil {
return nil
} else if strings.Contains(err.Error(), "failed to update secret") {
lastErr = err
continue // likely a transient version conflict
} else {
return err
}
}
return lastErr Prevention
- Serialize concurrent stack deploys to avoid version conflicts.
- Treat wrapped 'update out of sequence' errors as retriable.
- Avoid changing immutable secret fields; recreate the secret instead.
When it happens
Trigger: Redeploying a stack where a secret in compose.yml was modified, causing SecretUpdate at deploy_composefile.go:118 to return an error. Common when changing a field that the daemon rejects on update, or when the secret's version/meta is stale due to concurrent modification.
Common situations: Concurrent stack deploys racing on the same secret; changing an immutable attribute (e.g. driver labels) of an existing secret; manager node temporarily unhealthy; removing a secret out-of-band between the Inspect and Update calls.
Related errors
- failed to create secret
- failed to update config
- failed to update service
- when using secret driver secret data must be empty
- error reading from STDIN: data is empty
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/61742a120eb06c7b.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/stack/deploy_composefile.go:123
}
}
return nil
}
func createSecrets(ctx context.Context, dockerCLI command.Cli, secrets []swarm.SecretSpec) error {
apiClient := dockerCLI.Client()
for _, secretSpec := range secrets {
res, err := apiClient.SecretInspect(ctx, secretSpec.Name, client.SecretInspectOptions{})
switch {
case err == nil:
// secret already exists, then we update that
_, err := apiClient.SecretUpdate(ctx, res.Secret.ID, client.SecretUpdateOptions{
Version: res.Secret.Meta.Version,
Spec: secretSpec,
})
if err != nil {
return fmt.Errorf("failed to update secret %s: %w", secretSpec.Name, err)
}
case errdefs.IsNotFound(err):
// secret does not exist, then we create a new one.
_, _ = fmt.Fprintln(dockerCLI.Out(), "Creating secret", secretSpec.Name)
_, err := apiClient.SecretCreate(ctx, client.SecretCreateOptions{
Spec: secretSpec,
})
if err != nil {
return fmt.Errorf("failed to create secret %s: %w", secretSpec.Name, err)
}
default:
return err
}
}
return nil
}
func createConfigs(ctx context.Context, dockerCLI command.Cli, configs []swarm.ConfigSpec) error {View on GitHub (pinned to 4f84911bfe)