docker/cli · warning

could not fetch unlock key

Error message

could not fetch unlock key: %w

What it means

Thrown by 'docker swarm update' when autolocking was just enabled (curAutoLock && !prevAutoLock) and the follow-up SwarmGetUnlockKey call fails. The update itself succeeded, but the unlock key needed to display could not be fetched.

Solutions

  1. Retrieve the key once stable: 'docker swarm unlock-key'.
  2. Confirm autolock is now on via 'docker info' (look for autolock).
  3. If managers are now locked out, use 'docker swarm unlock' with a previously saved key.

Example fix

# before: update enabled autolock but key fetch failed
docker swarm update --autolock

# after: fetch the key explicitly after the update
docker swarm update --autolock
docker swarm unlock-key
Defensive patterns

Strategy: retry

Type guard

func isUnlockKeyFetchErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "could not fetch unlock key:")
}

Try / catch

if err := runUpdate(ctx, cli, flags, opts); err != nil {
    if isUnlockKeyFetchErr(err) {
        // update succeeded; fetch key separately
        _ = cli.RunDockerCmd("swarm", "unlock-key")
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Running 'docker swarm update --autolock=true' on a swarm where autolock was previously off; the subsequent key fetch at update.go:67-71 errors (daemon hiccup, manager instability right after the spec change).

Common situations: Manager under load right after a spec update; network flakiness; the update triggered a leadership change that briefly made the key endpoint unavailable.

Related errors


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

Appendix: source

Thrown at cli/command/swarm/update.go:70

	opts.mergeSwarmSpec(&sw.Swarm.Spec, flags, &sw.Swarm.ClusterInfo.TLSInfo.TrustRoot)

	curAutoLock := sw.Swarm.Spec.EncryptionConfig.AutoLockManagers

	_, err = apiClient.SwarmUpdate(ctx, client.SwarmUpdateOptions{
		Version: sw.Swarm.Version,
		Spec:    sw.Swarm.Spec,
	})
	if err != nil {
		return err
	}

	_, _ = fmt.Fprintln(dockerCLI.Out(), "Swarm updated.")

	if curAutoLock && !prevAutoLock {
		resp, err := apiClient.SwarmGetUnlockKey(ctx)
		if err != nil {
			return fmt.Errorf("could not fetch unlock key: %w", err)
		}
		printUnlockCommand(dockerCLI.Out(), resp.Key)
	}

	return nil
}

View on GitHub (pinned to 4f84911bfe)