🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Docker Multi-Platform Build Failing for ARM64/AMD64: How to Fix It

Building Docker images for both ARM64 and AMD64 fails with QEMU errors, manifest issues, or wrong architecture? Here are the exact fixes.

DevOpsBoys4 min read
Share:Tweet

Multi-platform Docker builds are increasingly common — Apple Silicon for development, AMD64 for production — but they fail in several specific, frustrating ways.

Common Error Messages

# QEMU error
ERROR: failed to solve: runtime execution on platform linux/arm64 is not supported

# Manifest error  
ERROR: multiple platforms feature is currently not supported for docker driver

# Wrong platform warning
WARNING: The requested image's platform (linux/amd64) does not match 
the detected host platform (linux/arm64/v8)

# BuildKit error
error: failed to create LLB definition: 
  Dockerfile parse error on line 5: unknown instruction: RUN

Fix 1: Enable Docker BuildKit and Buildx

Multi-platform builds require BuildKit and the buildx builder:

bash
# Check current builder
docker buildx ls
# If only "default" exists, create a new builder
 
# Create a multi-platform builder
docker buildx create --name multiplatform --driver docker-container --use
 
# Verify it's active
docker buildx ls
# Should show "multiplatform" with *
 
# Bootstrap the builder
docker buildx inspect --bootstrap

If you see only default as driver and it shows docker (not docker-container), that's the problem. The docker driver doesn't support multi-platform. You need docker-container.

Fix 2: Install QEMU for Cross-Platform Emulation

When building linux/arm64 on an amd64 host (or vice versa), Docker uses QEMU for emulation.

bash
# Install QEMU on Linux
docker run --privileged --rm tonistiigi/binfmt --install all
 
# Verify QEMU is installed
ls /proc/sys/fs/binfmt_misc/ | grep qemu
# Should show: qemu-aarch64, qemu-arm, etc.
 
# Verify in BuildKit
docker buildx inspect multiplatform
# Should show: Platforms: linux/amd64, linux/arm64, linux/arm/v7, ...

On macOS (Docker Desktop), QEMU support is built in — no manual install needed.

Fix 3: Multi-Platform Build Command

bash
# Build and push to registry (most common)
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag myrepo/myapp:latest \
  --push \
  .
 
# Build to local Docker daemon (only one platform at a time locally)
docker buildx build \
  --platform linux/arm64 \
  --tag myapp:arm64 \
  --load \  # --load only works with single platform
  .
 
# Build and save as tar (both platforms)
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag myapp:latest \
  --output type=oci,dest=./myapp.tar \
  .

Note: You cannot use --load with multiple platforms. Use --push to push to a registry, or build each platform separately with --load.

Fix 4: Platform-Specific Instructions in Dockerfile

Some commands behave differently on different architectures:

dockerfile
FROM ubuntu:22.04
 
# Use TARGETPLATFORM to handle differences
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
 
# Download platform-specific binary
RUN case ${TARGETPLATFORM} in \
  "linux/amd64") ARCH=amd64 ;; \
  "linux/arm64") ARCH=arm64 ;; \
  "linux/arm/v7") ARCH=armv7 ;; \
  *) echo "Unsupported platform: ${TARGETPLATFORM}" && exit 1 ;; \
esac && \
wget https://example.com/binary-${ARCH} -O /usr/local/bin/mybinary && \
chmod +x /usr/local/bin/mybinary

For Go builds, use the built-in cross-compilation:

dockerfile
FROM golang:1.22 AS builder
 
ARG TARGETOS
ARG TARGETARCH
 
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o server ./cmd/server

Go cross-compilation is native (no QEMU needed), making multi-platform Go builds much faster.

Fix 5: GitHub Actions Multi-Platform Build

yaml
name: Build Multi-Platform
 
on:
  push:
    branches: [main]
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: |
            myrepo/myapp:latest
            myrepo/myapp:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

The docker/setup-qemu-action step is critical — it installs QEMU for ARM emulation on the AMD64 runner.

Fix 6: Native ARM64 Builds (Faster Than Emulation)

QEMU emulation is slow. For production pipelines, use native runners:

yaml
jobs:
  build-amd64:
    runs-on: ubuntu-latest  # AMD64
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - name: Build AMD64
        uses: docker/build-push-action@v5
        with:
          platforms: linux/amd64
          push: true
          tags: myrepo/myapp:amd64
  
  build-arm64:
    runs-on: ubuntu-24.04-arm  # GitHub's native ARM64 runner
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - name: Build ARM64
        uses: docker/build-push-action@v5
        with:
          platforms: linux/arm64
          push: true
          tags: myrepo/myapp:arm64
  
  merge-manifest:
    needs: [build-amd64, build-arm64]
    runs-on: ubuntu-latest
    steps:
      - name: Create manifest
        run: |
          docker buildx imagetools create \
            --tag myrepo/myapp:latest \
            myrepo/myapp:amd64 \
            myrepo/myapp:arm64

Native ARM64 builds are 5-10x faster than QEMU emulation for compute-heavy builds.

Fix 7: Verify the Multi-Platform Image

bash
# Check what platforms the image supports
docker buildx imagetools inspect myrepo/myapp:latest
 
# Output should show:
# Manifests:
#   linux/amd64:
#     MediaType: application/vnd.oci.image.manifest.v1+json
#     ...
#   linux/arm64:
#     MediaType: application/vnd.oci.image.manifest.v1+json
#     ...
 
# Pull and run on specific platform
docker run --platform linux/arm64 myrepo/myapp:latest uname -m
# aarch64
 
docker run --platform linux/amd64 myrepo/myapp:latest uname -m
# x86_64

Summary Checklist

  • Using docker-container driver (not docker driver)
  • QEMU installed on Linux hosts (tonistiigi/binfmt --install all)
  • Using --push not --load for multi-platform builds
  • TARGETARCH/TARGETOS used correctly for platform-specific logic
  • GitHub Actions: docker/setup-qemu-action@v3 step included
  • Verified image with docker buildx imagetools inspect

Resources: Docker multi-platform build docs | GitHub ARM64 runners

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments