docker/cli · error

no tag or digest

Error message

%s no tag or digest

What it means

getManifestOptionsFromReference returns this when the reference is neither NamedTagged nor Canonical — i.e. it carries only a name with no :tag and no @digest. The distribution manifest API needs a tag or digest to locate a manifest, so a bare name is unusable at this layer.

Solutions

  1. Attach a tag with reference.WithTag(name, "latest") or reference.WithTag(name, desiredTag).
  2. Attach a digest with reference.WithDigest(name, dgst) for immutable pulls.
  3. Validate with a type assertion to reference.NamedTagged or reference.Canonical before calling.
  4. If the user supplied the value, surface a clear "tag or digest required" message upstream.

Example fix

// before
ref, _ := reference.ParseNamed("library/nginx")
c.GetManifest(ctx, ref) // -> no tag or digest

// after
ref, _ := reference.WithTag(reference.MustParseNamed("library/nginx"), "latest")
c.GetManifest(ctx, ref)
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the reference carries a tag or digest before calling the client.
func ensureTaggedOrDigested(ref reference.Named) (reference.Named, error) {
    switch r := ref.(type) {
    case reference.NamedTagged, reference.Canonical:
        return ref, nil
    }
    return reference.WithTag(ref, "latest")
}

Type guard

func hasTagOrDigest(ref reference.Named) bool {
    switch ref.(type) {
    case reference.NamedTagged, reference.Canonical:
        return true
    default:
        return false
    }
}

Prevention

When it happens

Trigger: Calling PutManifest (or getManifest via GetManifest/GetManifestList) with a reference like "nginx" or "library/nginx" that has no tag and no digest.

Common situations: Passing a bare image name expecting an implicit "latest"; programmatically trimming the tag off a ref; building a ref with reference.WithName and forgetting to attach a tag/digest.

Related errors


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

Appendix: source

Thrown at internal/registryclient/client.go:195

	fetch := func(ctx context.Context, repo distribution.Repository, ref reference.Named) (bool, error) {
		var err error
		result, err = fetchList(ctx, repo, ref)
		return len(result) > 0, err
	}

	err := c.iterateEndpoints(ctx, ref, fetch)
	return result, err
}

func getManifestOptionsFromReference(ref reference.Named) (digest.Digest, []distribution.ManifestServiceOption, error) {
	if tagged, isTagged := ref.(reference.NamedTagged); isTagged {
		tag := tagged.Tag()
		return "", []distribution.ManifestServiceOption{distribution.WithTag(tag)}, nil
	}
	if digested, isDigested := ref.(reference.Canonical); isDigested {
		return digested.Digest(), []distribution.ManifestServiceOption{}, nil
	}
	return "", nil, fmt.Errorf("%s no tag or digest", ref)
}

View on GitHub (pinned to 4f84911bfe)