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

  1. Sign by tag: 'docker trust sign repo/image:tag'.
  2. Tag the digest locally first: 'docker tag repo/image@sha256:... repo/image:v1' then sign the tag.
  3. 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

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


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 := &notaryclient.Target{}
	var err error
	if tag == "" {
		return *target, errors.New("no tag specified")
	}
	target.Name = tag

View on GitHub (pinned to 4f84911bfe)