docker/cli · error
failed to assemble ManifestDescriptor
Error message
failed to assemble ManifestDescriptor: %w
What it means
Returned by `printManifestList` (inspect.go:120-123) in the non-verbose path when `buildManifestDescriptor(targetRepo, img)` fails for any entry in the local manifest list. buildManifestDescriptor (push.go:143-168) fails on a registry-hostname mismatch between a source image and the target, or when the manifest digest fails validation.
Solutions
- Run `docker manifest inspect -v <list>` (verbose) which bypasses buildManifestDescriptor and reveals the offending entry.
- Re-create the manifest list ensuring all sources share the target registry hostname.
- Clear the local manifest store and re-create the list if the digest is corrupted.
- Annotate or re-add the offending image to refresh its descriptor.
Example fix
# before docker manifest inspect mylist # fails on registry mismatch in a member # after docker manifest inspect -v mylist # verbose path reveals the member; fix the source registry
Defensive patterns
Strategy: validation
Validate before calling
// pre-check each member's registry hostname and digest before printing non-verbose
for _, img := range list {
if reference.Domain(reference.TrimNamed(img.Ref)) != reference.Domain(reference.TrimNamed(target)) {
return fmt.Errorf("member %s registry differs from target; inspect -v to bypass", img.Ref)
}
if err := img.Descriptor.Digest.Validate(); err != nil {
return fmt.Errorf("member %s has invalid digest: %w", img.Ref, err)
}
} Try / catch
if err := printManifestList(cli, ref, list, opts); err != nil {
if strings.Contains(err.Error(), "failed to assemble ManifestDescriptor") {
// retry verbose path which skips descriptor assembly
return printManifestList(cli, ref, list, inspectOptions{verbose: true})
}
return err
} Prevention
- Use `docker manifest inspect -v` when members span registries.
- Keep all members on the same registry as the target.
- Rebuild the local list if digests are suspect.
When it happens
Trigger: Running `docker manifest inspect <list>` (non-verbose) where a constituent image's registry hostname differs from the list's hostname, or where a manifest entry carries a malformed digest.
Common situations: A manifest list created with sources from a different registry than the target, corrupted local manifest cache, or a manifest entry with an empty/invalid digest.
Related errors
- manifest must have an OS and Architecture to be pushed to a…
- cannot use source images from a different registry than the…
- digest parse of image
- internal digest mismatch for
- error mounting to
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/ced04d3330890c9d.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/manifest/inspect.go:122
}
jsonBytes, err := json.MarshalIndent(manifest, "", "\t")
if err != nil {
return err
}
_, _ = dockerCli.Out().Write(append(jsonBytes, '\n'))
return nil
}
func printManifestList(dockerCli command.Cli, namedRef reference.Named, list []types.ImageManifest, opts inspectOptions) error {
if !opts.verbose {
targetRepo := reference.TrimNamed(namedRef)
manifests := make([]manifestlist.ManifestDescriptor, 0, len(list))
// More than one response. This is a manifest list.
for _, img := range list {
mfd, err := buildManifestDescriptor(targetRepo, img)
if err != nil {
return fmt.Errorf("failed to assemble ManifestDescriptor: %w", err)
}
manifests = append(manifests, mfd)
}
deserializedML, err := manifestlist.FromDescriptors(manifests)
if err != nil {
return err
}
jsonBytes, err := deserializedML.MarshalJSON()
if err != nil {
return err
}
_, _ = fmt.Fprintln(dockerCli.Out(), string(jsonBytes))
return nil
}
jsonBytes, err := json.MarshalIndent(list, "", "\t")
if err != nil {
return err
}View on GitHub (pinned to 4f84911bfe)