Skip to content

fix: pin golang:1.26.2 to multi-arch index digest (arm64 exec format error on :master)#1131

Merged
psbrar99 merged 1 commit intoenvoyproxy:mainfrom
harrisonharris-di:fix/golang-1.26.2-multiarch-digest
May 7, 2026
Merged

fix: pin golang:1.26.2 to multi-arch index digest (arm64 exec format error on :master)#1131
psbrar99 merged 1 commit intoenvoyproxy:mainfrom
harrisonharris-di:fix/golang-1.26.2-multiarch-digest

Conversation

@harrisonharris-di
Copy link
Copy Markdown
Contributor

Summary

Pin the golang:1.26.2 base image in Dockerfile, Dockerfile.integration, and examples/xds-sotw-config-server/Dockerfile to the multi-arch OCI image index digest sha256:b54cbf583d390341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716, replacing the single-arch (linux/amd64) image manifest digest sha256:7095ad02810845fa35d1fb090b8e57dd20dce4ca36b29b42951802350d2ec90e introduced in #1124.

Image Digest Type
golang:1.26.1 (pre-#1124) e2ddb153… OCI image index (multi-arch)
golang:1.26.2 (current master, broken on arm64) 7095ad02… OCI image manifest (linux/amd64 only)
golang:1.26.2 (this PR) b54cbf58… OCI image index (multi-arch, includes the 7095ad02… amd64 child)

Problem

Since #1124 merged on 2026-04-30, every envoyproxy/ratelimit:master image published to Docker Hub contains the linux/amd64 binary inside the linux/arm64/v8 layer. On arm64 hosts the container fails immediately at startup:

exec /bin/ratelimit: exec format error

The arm64 layer in the published index is byte-identical to the amd64 layer at 9192208 bytes, vs the previous good build's separate 9151374 / 8398114 byte layers.

Root cause

The previous 1.26.1 pin used the multi-arch OCI image index digest sha256:e2ddb153f786... (mediaType: application/vnd.oci.image.index.v1+json), which fans out per-platform when buildx is asked for arm64.

The 1.26.2 pin introduced in #1124 (sha256:7095ad02...) is instead a single-arch image manifest (mediaType: application/vnd.oci.image.manifest.v1+json, config: os: linux, architecture: amd64) — there is no arm64 child to resolve to.

When buildx builds the arm64 variant, it pulls this amd64 base anyway, the Go compile targets amd64 regardless of the requested platform, and the published multi-arch manifest stamps that amd64 binary into the arm64 layer.

This is a known Docker UX footgun: docker pull <tag> on an amd64 host exposes the per-arch image digest in RepoDigests, not the index digest. Copy-pasting from there silently strips multi-arch support — the build only fails on non-amd64 targets, and amd64 CI runners stay green.

Fix

Use the corresponding multi-arch index digest for the same golang:1.26.2 tag. The new digest contains sha256:7095ad02... as its linux/amd64 child plus linux/arm64/v8 (sha256:9cad238cf0e0...) and the other platforms the 1.26.1 index covered. The amd64 image is byte-identical; only the broken arm64 path changes — from "silently produces an amd64 binary" to "produces an arm64 binary".

Verification

# Resolve golang:1.26.2 to its index digest:
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/golang:pull" | jq -r .token)
curl -sI -H "Authorization: Bearer $TOKEN" \
     -H "Accept: application/vnd.oci.image.index.v1+json" \
     "https://registry-1.docker.io/v2/library/golang/manifests/1.26.2" \
     | grep -i docker-content-digest
# docker-content-digest: sha256:b54cbf583d390341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716

# Confirm it's an index and contains the existing amd64 digest:
curl -s -H "Authorization: Bearer $TOKEN" \
     -H "Accept: application/vnd.oci.image.index.v1+json" \
     "https://registry-1.docker.io/v2/library/golang/manifests/sha256:b54cbf583d390341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716" \
     | jq '{mediaType, amd64: (.manifests[] | select(.platform.os=="linux" and .platform.architecture=="amd64") | .digest), arm64: (.manifests[] | select(.platform.os=="linux" and .platform.architecture=="arm64") | .digest)}'
# {
#   "mediaType": "application/vnd.oci.image.index.v1+json",
#   "amd64": "sha256:7095ad02810845fa35d1fb090b8e57dd20dce4ca36b29b42951802350d2ec90e",
#   "arm64": "sha256:9cad238cf0e0..."
# }

Risk

Low — amd64 image unchanged, arm64 path changes from broken-and-silent to working. No code changes; only FROM digest swap in three Dockerfiles.

PR envoyproxy#1124 updated the golang base image from 1.26.1 to 1.26.2, but the
new digest sha256:7095ad02810845fa35d1fb090b8e57dd20dce4ca36b29b42951
802350d2ec90e is a single-arch (linux/amd64) image manifest rather
than a multi-arch index. The previous 1.26.1 digest sha256:e2ddb153f7
86ee6210bf8c40f7f35490b3ff7d38be70d1a0d358ba64225f6428 is an OCI image
index covering linux/amd64, arm64/v8, arm/v7, 386, ppc64le, riscv64,
s390x and windows/amd64.

When buildx is asked to produce a non-amd64 variant of the published
envoyproxy/ratelimit image, the FROM line resolves to the amd64 base
on every platform, so the resulting binary is amd64 regardless of the
target. The multi-arch publish then stamps that amd64 binary into the
arm64 layer of the released index, producing an image that fails on
arm64 nodes with:

  exec /bin/ratelimit: exec format error

Swap to the corresponding multi-arch index digest sha256:b54cbf583d39
0341599d7bcbc062425c081105cc5ef6d170ced98ef9d047c716, which contains
the existing 7095ad02... amd64 manifest as one of its children plus
the arm64/v8 and other platform variants. The amd64 image is
unchanged; arm64 builds now produce arm64 binaries.

Signed-off-by: Harrison Harris <harrison.harris@xapien.com>
@harrisonharris-di
Copy link
Copy Markdown
Contributor Author

@envoyproxy/ratelimit-maintainers Could you please review? As a first-time contributor the workflows are gated on your approval however I've opened the same PR on my fork and all three jobs (check, precommits, build) pass.

You may also wish to consider deleting the envoyproxy/ratelimit:fe26676d tagged docker image since it's broken on non-amd64 systems.

I'm not familiar with contributing to public repos so please let me know if I'm missing anything, thanks!

Copy link
Copy Markdown

@jukie jukie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed this fixes arm64 builds

@jukie
Copy link
Copy Markdown

jukie commented May 7, 2026

CC @collin-lee

@psbrar99 psbrar99 merged commit ff28760 into envoyproxy:main May 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants