docker/cli · error
cannot use source images from a different registry than the…
Error message
cannot use source images from a different registry than the target image: %s != %s
What it means
Returned by `buildManifestDescriptor` (push.go:144-148) when the source image's registry hostname differs from the target manifest-list hostname. The Docker manifest-list push only supports sources and targets within the same registry because blob mounting is registry-scoped.
Solutions
- Use source images from the same registry hostname as the target list.
- Copy/retag the source images into the target registry first (`docker pull`, `docker tag`, `docker push`).
- Build a separate list per registry if multi-registry aggregation is needed.
- Confirm hostnames exactly match, including default docker.io normalization.
Example fix
# before docker manifest create reg-a.com/mylist reg-b.com/img:tag docker manifest push reg-a.com/mylist # registries differ # after docker pull reg-b.com/img:tag docker tag reg-b.com/img:tag reg-a.com/img:tag docker push reg-a.com/img:tag docker manifest create reg-a.com/mylist reg-a.com/img:tag
Defensive patterns
Strategy: validation
Validate before calling
targetHost := reference.Domain(reference.TrimNamed(targetRef))
for _, m := range manifests {
if reference.Domain(reference.TrimNamed(m.Ref)) != targetHost {
return fmt.Errorf("source %s is on a different registry than target %s; retag first", m.Ref, targetRef)
}
} Type guard
func sameRegistry(a, b reference.Named) bool {
return reference.Domain(reference.TrimNamed(a)) == reference.Domain(reference.TrimNamed(b))
} Try / catch
if err := runPush(ctx, cli, opts); err != nil {
if strings.Contains(err.Error(), "different registry than the target") {
return fmt.Errorf("%w — retag sources into the target registry first", err)
}
return err
} Prevention
- Keep all source images in the same registry as the target list.
- Retag and push sources into the target registry before creating the list.
- Compare hostnames exactly, accounting for docker.io normalization.
When it happens
Trigger: Running `docker manifest create registryA.com/mylist registryB.com/img:tag` then `docker manifest push registryA.com/mylist` — the registries differ.
Common situations: Aggregating images from multiple registries into one list, or mixing Docker Hub with a private registry.
Related errors
- manifest must have an OS and Architecture to be pushed to a…
- digest parse of image
- error mounting to
- refusing to amend an existing manifest list with no --amend…
- annotate: error parsing name for manifest list
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/84dd0627dbe570c2.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/manifest/push.go:147
imageManifest.Descriptor.Platform.Architecture == "" ||
imageManifest.Descriptor.Platform.OS == "" {
return nil, fmt.Errorf("manifest %s must have an OS and Architecture to be pushed to a registry", imageManifest.Ref)
}
descriptor, err := buildManifestDescriptor(targetRepo, imageManifest)
if err != nil {
return nil, err
}
descriptors = append(descriptors, descriptor)
}
return manifestlist.FromDescriptors(descriptors)
}
func buildManifestDescriptor(targetRepo reference.Named, imageManifest types.ImageManifest) (manifestlist.ManifestDescriptor, error) {
manifestRepoHostname := reference.Domain(reference.TrimNamed(imageManifest.Ref))
targetRepoHostname := reference.Domain(reference.TrimNamed(targetRepo))
if manifestRepoHostname != targetRepoHostname {
return manifestlist.ManifestDescriptor{}, fmt.Errorf("cannot use source images from a different registry than the target image: %s != %s", manifestRepoHostname, targetRepoHostname)
}
manifest := manifestlist.ManifestDescriptor{
Descriptor: distribution.Descriptor{
Digest: imageManifest.Descriptor.Digest,
Size: imageManifest.Descriptor.Size,
MediaType: imageManifest.Descriptor.MediaType,
},
}
platform := types.PlatformSpecFromOCI(imageManifest.Descriptor.Platform)
if platform != nil {
manifest.Platform = *platform
}
if err := manifest.Descriptor.Digest.Validate(); err != nil {
return manifestlist.ManifestDescriptor{}, fmt.Errorf("digest parse of image %q failed: %w", imageManifest.Ref, err)
}View on GitHub (pinned to 4f84911bfe)