docker/cli · error

image manifest for does not exist

Error message

image manifest for %q does not exist

What it means

getManifest wraps the error from getManifestOptionsFromReference, whose only failure is the bare-reference case (error 602). So this message appears when the reference has neither a tag nor a digest — phrased as "does not exist" because without a tag/digest there is no way to address the manifest.

Solutions

  1. Attach a tag with reference.WithTag(ref, "latest") (or the intended tag).
  2. Attach a digest with reference.WithDigest(ref, dgst) for immutable addressing.
  3. Type-assert to reference.NamedTagged or reference.Canonical before calling.
  4. Surface a user-facing "tag or digest required" error at the input boundary.

Example fix

// before
ref, _ := reference.ParseNamed("library/nginx")
c.GetManifest(ctx, ref) // -> image manifest does not exist

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

Strategy: validation

Validate before calling

// Require a tag or digest before any manifest fetch.
func requireAddressable(ref reference.Named) (reference.Named, error) {
    switch ref.(type) {
    case reference.NamedTagged, reference.Canonical:
        return ref, nil
    }
    return nil, fmt.Errorf("reference %s has no tag or digest", ref)
}

Type guard

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

Prevention

When it happens

Trigger: Fetching a manifest via a reference that is only a name ("nginx", "library/nginx") with no :tag and no @digest.

Common situations: Passing an untagged reference expecting an implicit latest; stripping the tag during ref manipulation; constructing a ref with reference.WithName alone.

Related errors


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

Appendix: source

Thrown at internal/registryclient/fetcher.go:66

	}

	switch v := manifest.(type) {
	case *manifestlist.DeserializedManifestList:
		return pullManifestList(ctx, ref, repo, *v)
	default:
		return nil, fmt.Errorf("unsupported manifest format: %v", v)
	}
}

func getManifest(ctx context.Context, repo distribution.Repository, ref reference.Named) (distribution.Manifest, error) {
	manSvc, err := repo.Manifests(ctx)
	if err != nil {
		return nil, err
	}

	dgst, opts, err := getManifestOptionsFromReference(ref)
	if err != nil {
		return nil, fmt.Errorf("image manifest for %q does not exist", ref)
	}
	return manSvc.Get(ctx, dgst, opts...)
}

func pullManifestSchemaV2(ctx context.Context, ref reference.Named, repo distribution.Repository, mfst schema2.DeserializedManifest) (types.ImageManifest, error) {
	manifestDesc, err := validateManifestDigest(ref, mfst)
	if err != nil {
		return types.ImageManifest{}, err
	}
	configJSON, err := pullManifestSchemaV2ImageConfig(ctx, mfst.Target().Digest, repo)
	if err != nil {
		return types.ImageManifest{}, err
	}

	if manifestDesc.Platform == nil {
		manifestDesc.Platform = &ocispec.Platform{}
	}

View on GitHub (pinned to 4f84911bfe)