docker/cli · warning
is a manifest list
Error message
%s is a manifest list
What it means
fetchManifest (used by GetManifest, the single-manifest API) errors when the referenced image resolves to a manifest list / OCI index rather than a single-platform manifest. The data is fine; you asked for one manifest but the image is multi-arch. Use GetManifestList to enumerate the platform-specific entries.
Solutions
- Call GetManifestList instead to fetch all platform-specific manifests.
- Or resolve a specific platform digest first (e.g. via docker manifest inspect) and call GetManifest on that digest.
- Inspect the image with `docker manifest inspect <ref>` to confirm it is a list.
- If your pipeline only supports single manifests, build a platform-specific tag instead of a multi-arch one.
Example fix
// before m, err := c.GetManifest(ctx, ref) // -> is a manifest list // after list, err := c.GetManifestList(ctx, ref)
Defensive patterns
Strategy: fallback
Validate before calling
// When unsure whether an image is a list, prefer the list API.
func fetchAny(ctx context.Context, c RegistryClient, ref reference.Named) ([]types.ImageManifest, error) {
if list, err := c.GetManifestList(ctx, ref); err == nil {
return list, nil
}
m, err := c.GetManifest(ctx, ref)
if err != nil {
return nil, err
}
return []types.ImageManifest{m}, nil
} Try / catch
// Catch the manifest-list case and fall back to the list API.
var le listErr // your sentinel wrapping the message
if errors.As(err, &le) {
return c.GetManifestList(ctx, ref)
} Prevention
- Default to GetManifestList for public images that are commonly multi-arch.
- Use `docker manifest inspect` to learn an image's type before scripting.
- Branch on media type when you have it rather than guessing.
When it happens
Trigger: Calling GetManifest on a multi-arch image such as "nginx:latest" whose top-level object is a manifest list; the type switch in fetchManifest hits the manifestlist branch.
Common situations: Not realizing a popular image ships as a manifest list; calling the single-manifest endpoint by default; tooling that assumes every image is a single manifest.
Related errors
- unsupported manifest format
- unsupported manifest type: %T
- failed to put manifest
- is not a manifest
- refusing to amend an existing manifest list with no --amend…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/d0252b083e3e3bca.
Report an issue: GitHub.
Appendix: source
Thrown at internal/registryclient/fetcher.go:39
"github.com/sirupsen/logrus"
)
// fetchManifest pulls a manifest from a registry and returns it. An error
// is returned if no manifest is found matching namedRef.
func fetchManifest(ctx context.Context, repo distribution.Repository, ref reference.Named) (types.ImageManifest, error) {
manifest, err := getManifest(ctx, repo, ref)
if err != nil {
return types.ImageManifest{}, err
}
switch v := manifest.(type) {
// Removed Schema 1 support
case *schema2.DeserializedManifest:
return pullManifestSchemaV2(ctx, ref, repo, *v)
case *ocischema.DeserializedManifest:
return pullManifestOCISchema(ctx, ref, repo, *v)
case *manifestlist.DeserializedManifestList:
return types.ImageManifest{}, fmt.Errorf("%s is a manifest list", ref)
}
return types.ImageManifest{}, fmt.Errorf("%s is not a manifest", ref)
}
func fetchList(ctx context.Context, repo distribution.Repository, ref reference.Named) ([]types.ImageManifest, error) {
manifest, err := getManifest(ctx, repo, ref)
if err != nil {
return nil, err
}
switch v := manifest.(type) {
case *manifestlist.DeserializedManifestList:
return pullManifestList(ctx, ref, repo, *v)
default:
return nil, fmt.Errorf("unsupported manifest format: %v", v)
}
}
View on GitHub (pinned to 4f84911bfe)