{"record":{"id":"46109f281af71cd7","repo":"docker/cli","slug":"could-not-remove-signature-for-s-w","errorCode":null,"errorMessage":"could not remove signature for %s: %w","messagePattern":"could not remove signature for (.+?): %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/docker-trust/trust/revoke.go","lineNumber":66,"sourceCode":"\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !deleteRemote {\n\t\t\treturn cancelledErr{errors.New(\"trust revoke has been cancelled\")}\n\t\t}\n\t}\n\n\tnotaryRepo, err := newNotaryClient(dockerCLI, imgRefAndAuth, trust.ActionsPushAndPull)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = clearChangeList(notaryRepo); err != nil {\n\t\treturn err\n\t}\n\tdefer clearChangeList(notaryRepo)\n\tif err := revokeSignature(notaryRepo, tag); err != nil {\n\t\treturn fmt.Errorf(\"could not remove signature for %s: %w\", remote, err)\n\t}\n\t_, _ = fmt.Fprintf(dockerCLI.Out(), \"Successfully deleted signature for %s\\n\", remote)\n\treturn nil\n}\n\ntype cancelledErr struct{ error }\n\nfunc (cancelledErr) Cancelled() {}\n\nfunc revokeSignature(notaryRepo client.Repository, tag string) error {\n\tif tag != \"\" {\n\t\t// Revoke signature for the specified tag\n\t\tif err := revokeSingleSig(notaryRepo, tag); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// revoke all signatures for the image, as no tag was given\n\t\tif err := revokeAllSigs(notaryRepo); err != nil {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cmd/docker-trust/trust/revoke.go#L48-L84","documentation":"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.).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the image was signed: run `docker trust inspect <image>:<tag>` and confirm signer metadata exists before revoking.","Check connectivity to the notary server (the registry's notary/grafeas endpoint) and that your registry supports content trust.","Re-authenticate with `docker login <registry>` to ensure push-scope credentials are current.","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).","Inspect the wrapped %w error text for the notary-specific cause (e.g. ErrRepoNotInitialized, ErrRepositoryNotExist) and address that root cause."],"exampleFix":"// before\n$ docker trust revoke myimage\nError: could not remove signature for myimage: ...\n\n// after — ensure the image is signed and credentials are valid\n$ docker login registry.example.com\n$ docker trust inspect registry.example.com/myimage:latest   # confirm signed\n$ docker trust revoke registry.example.com/myimage:latest -y","handlingStrategy":"validation","validationCode":"// Before revoking, confirm the image is signed and reachable\n// shell pre-check (caller-side):\n//   docker trust inspect <image>:<tag> >/dev/null 2>&1 && docker trust revoke <image>:<tag> -y\n// In Go code wrapping the CLI:\nfunc canRevoke(repo, tag string) error {\n    if tag == \"\" { return errors.New(\"tag required for revoke pre-check\") }\n    // run `docker trust inspect` and assert a signer entry exists\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// When invoking docker trust revoke programmatically, treat the wrapped error as fatal\n// but distinguish transient (network) from permanent (not signed) via the %w text:\nout, err := exec.CommandContext(ctx, \"docker\", \"trust\", \"revoke\", ref, \"-y\").CombinedOutput()\nif err != nil {\n    if strings.Contains(string(out), \"no signed tags\") { /* nothing to revoke */ return nil }\n    return fmt.Errorf(\"revoke failed: %s: %w\", string(out), err)\n}","preventionTips":["Always sign images in CI right after push so revoke targets exist.","Pin registry credentials with push scope in CI before revoke steps.","Run `docker trust inspect` as a precondition check in automation before revoke."],"tags":["docker","trust","notary","signing","registry"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}