A 429 means the upstream throttled the request, you exceeded its rate limit. It is transient and retryable: backing off, or authenticating for a higher limit, clears it.
What this error means
An install or pull fails with 429 Too Many Requests (e.g. Docker Hub anonymous limits). Waiting and retrying, or authenticating, succeeds with no change to the request.
shell
Error response from daemon: toomanyrequests: You have reached your pull rate limit.
##[error] 429 Too Many Requests
Common causes
Anonymous or shared-IP rate limits
Unauthenticated pulls from a shared CI IP hit per-IP limits quickly (Docker Hub is a common case).
A burst of requests in a short window
Highly parallel jobs hammering one API can trip its rate limiter.
How to fix it
Back off and respect Retry-After
Honor the throttle and retry after the indicated delay.
shell
for i in 1 2 3 4 5; do
curl -fsSL "$URL" -o out && break
sleep $((i*15))
done
Authenticate and cache
Log in to the registry to get a higher rate limit.
Use a pull-through cache/mirror for images.
Cache dependencies so repeat runs do not re-fetch.
How to prevent it
Authenticate to registries in CI.
Cache images and dependencies.
On managed runners, transient 429 throttling is detected and the job is automatically retried with backoff, so a one-off rate limit does not fail the build.
Frequently asked questions
What causes "429 rate limit"?
Unauthenticated pulls from a shared CI IP hit per-IP limits quickly (Docker Hub is a common case).
How do I fix 429 rate limit?
Honor the throttle and retry after the indicated delay.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.