docker/cli · error

could not remove signature for

Error message

could not remove signature for %s: %w

What it means

Returned by `docker trust revoke` when the underlying notary client cannot remove the signature(s) for the given image reference. The error wraps the notary client failure that occurs inside revokeSignature(), which either removes a single tag's signature (revokeSingleSig) or all signatures (revokeAllSigs) and then calls notaryRepo.Publish(). The %s is the user-supplied IMAGE[:TAG] and %w is the raw notary error (network failure, missing trust data, permission error, etc.).

Solutions

  1. Verify the image was signed: run `docker trust inspect <image>:<tag>` and confirm signer metadata exists before revoking.
  2. Check connectivity to the notary server (the registry's notary/grafeas endpoint) and that your registry supports content trust.
  3. Re-authenticate with `docker login <registry>` to ensure push-scope credentials are current.
  4. If no tag is given and you intend to revoke all signatures, pass `-y` to skip the prompt and confirm the repo has signed tags (otherwise you hit the earlier 'no signed tags to remove' guard).
  5. Inspect the wrapped %w error text for the notary-specific cause (e.g. ErrRepoNotInitialized, ErrRepositoryNotExist) and address that root cause.

Example fix

// before
$ docker trust revoke myimage
Error: could not remove signature for myimage: ...

// after — ensure the image is signed and credentials are valid
$ docker login registry.example.com
$ docker trust inspect registry.example.com/myimage:latest   # confirm signed
$ docker trust revoke registry.example.com/myimage:latest -y
Defensive patterns

Strategy: validation

Validate before calling

// Before revoking, confirm the image is signed and reachable
// shell pre-check (caller-side):
//   docker trust inspect <image>:<tag> >/dev/null 2>&1 && docker trust revoke <image>:<tag> -y
// In Go code wrapping the CLI:
func canRevoke(repo, tag string) error {
    if tag == "" { return errors.New("tag required for revoke pre-check") }
    // run `docker trust inspect` and assert a signer entry exists
    return nil
}

Try / catch

// When invoking docker trust revoke programmatically, treat the wrapped error as fatal
// but distinguish transient (network) from permanent (not signed) via the %w text:
out, err := exec.CommandContext(ctx, "docker", "trust", "revoke", ref, "-y").CombinedOutput()
if err != nil {
    if strings.Contains(string(out), "no signed tags") { /* nothing to revoke */ return nil }
    return fmt.Errorf("revoke failed: %s: %w", string(out), err)
}

Prevention

When it happens

Trigger: Calling `docker trust revoke <image>:<tag>` or `docker trust revoke <image>` when the notary server is unreachable, the trust repository has not been initialized, the tag has no signed target (GetTargetByName fails), or Publish() fails to push metadata changes. Also triggered when the caller lacks push credentials to the registry's notary service.

Common situations: Operating against a registry without Content Trust/Notary enabled; revoking an image that was never signed; expired or missing notary delegation keys in ~/.docker/trust; network proxies intercepting the notary endpoint; rotating registry credentials so the stored auth no longer has push scope.

Related errors


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

Appendix: source

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

		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
}

type cancelledErr struct{ error }

func (cancelledErr) Cancelled() {}

func revokeSignature(notaryRepo client.Repository, tag string) error {
	if tag != "" {
		// Revoke signature for the specified tag
		if err := revokeSingleSig(notaryRepo, tag); err != nil {
			return err
		}
	} else {
		// revoke all signatures for the image, as no tag was given
		if err := revokeAllSigs(notaryRepo); err != nil {

View on GitHub (pinned to 4f84911bfe)