Self-Healing CI: Auto-Retrying a ghcr.io 429 Pull Rate Limit
A ghcr.io pull failing with 429 was throttled: the tag exists and your credentials are fine, the registry declined to serve that request right then.
The problem
A docker pull or a container job fails resolving an image hosted on ghcr.io, with a 429 in the message. The image and tag exist. Anonymous or token pulls from ghcr.io carry a request budget, and CI hitting the same image across many parallel jobs consumes it quickly.
Error response from daemon: failed to resolve reference "ghcr.io/acme/app:latest": ghcr.io/acme/app:latest: 429 Too Many RequestsWhy it happens
A matrix build multiplies pulls: every job pulls the same base image at the same moment, so a single workflow can exhaust the budget on its own.
The 429 can surface either from the daemon resolving the reference or from a blob read partway through the download, so the same throttle appears in two quite different looking frames.
The manual fix
Manual mitigations for a ghcr.io pull limit:
- Authenticate the pull so it counts against a larger budget than the anonymous one.
- Mirror the image into a registry you control, or use a pull-through cache.
- Re-run the job once the window has passed.
echo "$GITHUB_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdinHow this gets automated
Like every rate limit, this one is defined by a reset rather than a defect, so waiting is the whole fix. What makes it worth automating is the shape of the failure in a matrix: one throttled pull fails one leg, and the job that fails is usually not the one that consumed the budget. A self-healing pipeline backs off well past the window and retries the pull, so a build is not lost to a limit that has already expired.