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

  1. Use source images from the same registry hostname as the target list.
  2. Copy/retag the source images into the target registry first (`docker pull`, `docker tag`, `docker push`).
  3. Build a separate list per registry if multi-registry aggregation is needed.
  4. 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

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


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)