Docker "buildx imagetools create failed" in CI
docker buildx imagetools create assembles a manifest list from existing per-architecture tags already in a registry. It fails when one of the source tags does not exist, the target registry rejects the manifest list, or the credential cannot write the combined tag.
What this error means
A docker buildx imagetools create -t <tag> <src...> fails - a source manifest is not found, or the push of the assembled list is denied/rejected.
ERROR: failed to create manifest list ghcr.io/myorg/api:1.4.2: ghcr.io/myorg/api:1.4.2-arm64: not foundDiagnose it: separate auth from naming from rate limits
Registry errors look alike and have unrelated causes. Work out which of the three you have before changing credentials, because a malformed image reference produces an error that reads like an authentication failure.
# 1. is the reference even valid? (lowercase, no spaces, valid tag)
docker image inspect "$IMAGE" 2>&1 | head -2
# 2. are you authenticated to the right registry?
cat ~/.docker/config.json | grep -o '"[^"]*\.[^"]*"' | head
# 3. are you rate limited? (Docker Hub anonymous pulls)
curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimit-preview/test:pull" \
| grep -o '"token"' >/dev/null && echo "token ok"Common causes
A source per-arch tag is missing
imagetools create references tags that must already exist in the registry; a missing one fails the list.
The credential cannot write the target tag
Writing the combined manifest list needs push permission on the target repository.
The registry rejects the manifest list
A registry without OCI/list support can refuse the assembled manifest.
How to fix it
Push all source tags before combining
- Build and push each per-arch tag first.
- Then create the manifest list from those tags.
docker buildx imagetools create -t ghcr.io/myorg/api:1.4.2 \
ghcr.io/myorg/api:1.4.2-amd64 \
ghcr.io/myorg/api:1.4.2-arm64Inspect the source tags and auth
- Confirm each source tag resolves and you are logged in with write rights.
docker buildx imagetools inspect ghcr.io/myorg/api:1.4.2-amd64
docker login ghcr.io -u myorg --password-stdin <<< "$REGISTRY_TOKEN"Authenticate in the job, not in the image
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# GHCR needs this on the job or the push is rejected as unauthorised
permissions:
contents: read
packages: writeHow to prevent it
- Push every per-arch tag before assembling the list.
- Ensure the target credential has write access.
- Use a registry that supports manifest lists.