docker/cli · info · cancelledErr

trust revoke has been cancelled

Error message

trust revoke has been cancelled

What it means

Returned by revokeTrust (wrapped in a cancelledErr that implements Cancelled()) when no tag was supplied and the user answered 'No' to the confirmation prompt asking whether to delete all signature data for the repository. It is a user-initiated cancellation, not a system failure.

Solutions

  1. Re-run and answer 'y' at the prompt if you really want to revoke all signatures.
  2. Pass -y/--yes to skip the confirmation in scripts: 'docker trust revoke -y repo/image'.
  3. Specify a single tag to revoke instead of all signatures if you only meant one.

Example fix

# before: docker trust revoke repo/image  -> answered No
# after:  docker trust revoke -y repo/image   # or revoke one tag: docker trust revoke repo/image:v1
Defensive patterns

Strategy: validation

Validate before calling

// Detect the cancelledErr type (implements Cancelled()) and treat as non-fatal
func isRevokeCancelled(err error) bool {
	type cancelled interface{ Cancelled() }
	var c cancelled
	return errors.As(err, &c)
}

Type guard

// Type guard for the cancellation sentinel
func isCancelledErr(err error) bool {
	type cancelled interface{ Cancelled() }
	var c cancelled
	return errors.As(err, &c)
}

Try / catch

// In wrapping code, suppress cancelledErr instead of surfacing it as a failure
err := revokeTrust(...)
if isRevokeCancelled(err) {
    // user chose not to revoke — exit cleanly
    return nil
}
return err

Prevention

When it happens

Trigger: Running 'docker trust revoke repo/image' (no tag) without -y; the prompt.Confirm call returns false, so revokeTrust returns cancelledErr at revoke.go:52.

Common situations: User hesitates about deleting all signatures; a non-interactive shell where the prompt defaults to no; scripting without -y that aborts on the safety check.

Related errors


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

Appendix: source

Thrown at cmd/docker-trust/trust/revoke.go:52

	return cmd
}

func revokeTrust(ctx context.Context, dockerCLI command.Cli, remote string, options revokeOptions) error {
	imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, authResolver(dockerCLI), remote)
	if err != nil {
		return err
	}
	tag := imgRefAndAuth.Tag()
	if imgRefAndAuth.Tag() == "" && imgRefAndAuth.Digest() != "" {
		return errors.New("cannot use a digest reference for IMAGE:TAG")
	}
	if imgRefAndAuth.Tag() == "" && !options.forceYes {
		deleteRemote, err := prompt.Confirm(ctx, dockerCLI.In(), dockerCLI.Out(), fmt.Sprintf("Confirm you would like to delete all signature data for %s?", remote))
		if err != nil {
			return err
		}
		if !deleteRemote {
			return cancelledErr{errors.New("trust revoke has been cancelled")}
		}
	}

	notaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)
	if err != nil {
		return err
	}

	if err = clearChangeList(notaryRepo); err != nil {
		return err
	}
	defer clearChangeList(notaryRepo)
	if err := revokeSignature(notaryRepo, tag); err != nil {
		return fmt.Errorf("could not remove signature for %s: %w", remote, err)
	}
	_, _ = fmt.Fprintf(dockerCLI.Out(), "Successfully deleted signature for %s\n", remote)
	return nil
}

View on GitHub (pinned to 4f84911bfe)