docker/cli · error
cannot push a digest reference
Error message
cannot push a digest reference
What it means
Returned by PushTrustedReference when the image reference is a digest reference (reference.Digested, e.g. image@sha256:abc...). Docker Content Trust signs tags, not content-addressable digests, so a digest reference has no tag to attach a signature to and is rejected before any push.
Solutions
- Push by tag instead of digest: 'docker push repo/image:tag'.
- If you must move a digest, push the manifest by tag first so trust can attach to the tag, then reference the digest for pulls.
- Disable DCT for the specific operation only if signing is not required: DOCKER_CONTENT_TRUST=0.
Example fix
# before: docker push myrepo/img@sha256:abcd... # after: docker tag myrepo/img@sha256:abcd... myrepo/img:v1 && docker push myrepo/img:v1
Defensive patterns
Strategy: validation
Validate before calling
// Reject digest references before attempting a trusted push
func isDigestRef(ref reference.Named) bool {
_, ok := ref.(reference.Digested)
return ok
}
// if isDigestRef(ref) { return errors.New("use a tag, not a digest, for trusted push") } Type guard
// Type guard narrowing to a taggable reference
func isTagged(ref reference.Named) bool {
_, ok := ref.(reference.Tagged)
return ok
} Prevention
- Always push by tag when DOCKER_CONTENT_TRUST is enabled.
- Resolve references to tags, not digests, before trusted push.
- In code, type-switch on the reference and reject reference.Digested in the push path.
When it happens
Trigger: Performing a trusted push (DOCKER_CONTENT_TRUST=1) of an image specified by digest, e.g. 'docker push repo/image@sha256:...'. The type switch at trust_push.go:73 hits the Digested case and returns immediately.
Common situations: Pin-to-digest CI pipelines that also enable content trust; scripting that resolves an image to a digest and then pushes under DCT; copy-pasting a digest reference where a tag is expected.
Related errors
- cannot use a digest reference for IMAGE:TAG
- cannot use a digest reference for IMAGE:TAG
- no targets found, provide a specific tag in order to sign it
- no valid signing keys for delegation roles
- could not decrypt key
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/14f539a9311504a8.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/internal/trust/trust_push.go:75
err := json.Unmarshal(*msg.Aux, &pushResult)
if err == nil && pushResult.Tag != "" {
if dgst, err := digest.Parse(pushResult.Digest); err == nil {
h, err := hex.DecodeString(dgst.Hex())
if err != nil {
notaryTarget = nil
return
}
notaryTarget.Name = pushResult.Tag
notaryTarget.Hashes = data.Hashes{string(dgst.Algorithm()): h}
notaryTarget.Length = int64(pushResult.Size)
}
}
}
var tag string
switch x := ref.(type) {
case reference.Digested:
return errors.New("cannot push a digest reference")
case reference.Tagged:
tag = x.Tag()
default:
// We want trust signatures to always take an explicit tag,
// otherwise it will act as an untrusted push.
if err := jsonstream.Display(ctx, in, ioStreams.Out()); err != nil {
return err
}
_, _ = fmt.Fprintln(ioStreams.Err(), "No tag specified, skipping trust metadata push")
return nil
}
if err := jsonstream.Display(ctx, in, ioStreams.Out(), jsonstream.WithAuxCallback(handleTarget)); err != nil {
return err
}
if cnt > 1 {
return errors.New("internal error: only one call to handleTarget expected")View on GitHub (pinned to 4f84911bfe)