docker/cli · warning

unsupported manifest format

Error message

unsupported manifest format: %v

What it means

fetchList (used by GetManifestList) only accepts a DeserializedManifestList. This fires when the referenced image is a single manifest (schema2 or OCI), not a list — the mirror of error 604. The image exists; it is just not multi-arch.

Solutions

  1. Call GetManifest for single-manifest images.
  2. Build and push a manifest list with `docker manifest create` if you need multi-arch semantics.
  3. Detect the media type first and branch to the right API.
  4. Use `docker manifest inspect <ref>` to see whether the image is a list or a single manifest.

Example fix

// before
list, err := c.GetManifestList(ctx, ref) // -> unsupported manifest format

// after
m, err := c.GetManifest(ctx, ref)
Defensive patterns

Strategy: fallback

Validate before calling

// Try list first; if it is a single manifest, fall back to GetManifest.
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

// Single manifest served where a list was expected -> use single API.
var se singleErr
if errors.As(err, &se) {
    if m, e2 := c.GetManifest(ctx, ref); e2 == nil {
        return []types.ImageManifest{m}, nil
    }
}

Prevention

When it happens

Trigger: Calling GetManifestList on a single-platform image whose top-level object is a plain manifest, not an index/list.

Common situations: Treating every image as multi-arch; a platform-specific tag that was never assembled into a manifest list.

Related errors


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

Appendix: source

Thrown at internal/registryclient/fetcher.go:54

	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)
	}
}

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)

View on GitHub (pinned to 4f84911bfe)