Skip to content
Latchkey

Docker "toomanyrequests: rate limit exceeded" - Fix Docker Hub Pull Limits

Docker Hub enforces anonymous pull-rate limits per IP. On shared CI infrastructure you share that IP with everyone else on the runner pool, so unauthenticated pulls hit the limit quickly.

What this error means

An image pull fails with a 429 Too Many Requests from Docker Hub. It is intermittent by nature - the same workflow passes minutes later once the limit window resets.

docker pull output
Error response from daemon: toomanyrequests: You have reached your pull rate
limit. You may increase the limit by authenticating and upgrading:
https://www.docker.com/increase-rate-limit

Common causes

Anonymous pulls share an IP-based quota

Hosted CI runners pull from a shared NAT IP. Docker Hub counts pulls per IP for anonymous users, so your job is rate-limited by everyone else’s pulls too.

No authentication

Authenticated pulls get a much higher quota tied to your account rather than the shared runner IP.

How to fix it

Authenticate to Docker Hub

Log in with an access token before pulling. This moves you off the anonymous shared-IP quota.

.github/workflows/build.yml
- name: Log in to Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

Cache or mirror base images

  1. Pull base images through a registry mirror or your cloud provider’s registry cache.
  2. Mirror frequently-used base images into your own registry (GHCR, ECR, Artifact Registry) and pull from there.
  3. Cache built images between runs so you do not re-pull bases on every job.

Add a bounded retry

Because the limit is a transient, time-windowed condition, a short backoff retry often succeeds without any other change.

How to prevent it

  • Always authenticate to Docker Hub in CI, even for public images.
  • Pull base images from a registry you control or a pull-through cache.
  • Pin base image digests so cached layers are reused.

Frequently asked questions

Do authenticated pulls completely remove the limit?
They raise it substantially and tie it to your account instead of the shared runner IP. Paid plans raise it further. For heavy pipelines, a pull-through cache or your own registry is the durable fix.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →