docker/cli · error
cannot use a digest reference for IMAGE:TAG
Error message
cannot use a digest reference for IMAGE:TAG
What it means
Returned by validateTag (called from runSignImage) when the image reference has a digest but no tag. Signing requires a concrete tag to attach the trust target to; a digest-only reference is rejected at sign.go:138-139 before any Notary interaction.
Solutions
- Sign by tag: 'docker trust sign repo/image:tag'.
- Tag the digest locally first: 'docker tag repo/image@sha256:... repo/image:v1' then sign the tag.
- Adjust CI to pass the tag reference, not the resolved digest, to docker trust sign.
Example fix
# before: docker trust sign myrepo/img@sha256:abcd... # after: docker tag myrepo/img@sha256:abcd... myrepo/img:v1 && docker trust sign myrepo/img:v1
Defensive patterns
Strategy: validation
Validate before calling
// Reject digest references before signing
func validateSignRef(ref trust.ImageRefAndAuth) error {
if ref.Tag() == "" {
if ref.Digest() != "" {
return errors.New("cannot use a digest reference for IMAGE:TAG")
}
return fmt.Errorf("no tag specified for %s", ref.Name())
}
return nil
} Type guard
// Ensure a tag is present for signing
func isTaggedForSign(ref trust.ImageRefAndAuth) bool {
return ref.Tag() != ""
} Prevention
- Pass a tag to docker trust sign, not a digest.
- In CI, resolve and pass the tag rather than the canonical digest.
- Type-check references in code to reject reference.Digested in the sign path.
When it happens
Trigger: Running 'docker trust sign repo/image@sha256:...' — Tag() returns '' while Digest() is set, so validateTag returns this error.
Common situations: Resolving an image to a digest in a script and passing it to trust sign; copy-pasting a digest from docker inspect; pinning by digest in a signed-build pipeline.
Related errors
- cannot push a digest reference
- cannot use a digest reference for IMAGE:TAG
- no tag specified
- no valid signing keys for delegation roles
- no targets found, provide a specific tag in order to sign it
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/47336807c99e41c2.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/trust/sign.go:139
return err
}
err = trust.AddToAllSignableRoles(notaryRepo, &target)
if err == nil {
prettyPrintExistingSignatureInfo(out, existingSigInfo)
err = notaryRepo.Publish()
}
if err != nil {
return fmt.Errorf("failed to sign %s:%s: %w", imgRefAndAuth.RepoInfo().Name.Name(), tag, err)
}
_, _ = fmt.Fprintf(out, "Successfully signed %s:%s\n", imgRefAndAuth.RepoInfo().Name.Name(), tag)
return nil
}
func validateTag(imgRefAndAuth trust.ImageRefAndAuth) error {
tag := imgRefAndAuth.Tag()
if tag == "" {
if imgRefAndAuth.Digest() != "" {
return errors.New("cannot use a digest reference for IMAGE:TAG")
}
return fmt.Errorf("no tag specified for %s", imgRefAndAuth.Name())
}
return nil
}
func checkLocalImageExistence(ctx context.Context, apiClient client.APIClient, imageName string) error {
_, err := apiClient.ImageInspect(ctx, imageName)
return err
}
func createTarget(notaryRepo notaryclient.Repository, tag string) (notaryclient.Target, error) {
target := ¬aryclient.Target{}
var err error
if tag == "" {
return *target, errors.New("no tag specified")
}
target.Name = tagView on GitHub (pinned to 4f84911bfe)