429 Too Many Requests

Container Registry Pull Rate Limit Exceeded — Fix Now

Server & Cloud Beginner 👁 10 views 📅 Jun 16, 2026

You hit Docker Hub's anonymous pull limit. The fix is authenticated pulls. Here's the exact command and why it works.

You ran into Docker's pull rate limit. It's annoying, and it stops your builds cold.

Let's fix it.

The Fix — Authenticate Your Pulls

What's actually happening here is that Docker Hub enforces a rate limit on unauthenticated (anonymous) pulls. As of Docker Hub's policy changes in November 2020, anonymous users are limited to 100 pulls per 6 hours. Authenticated (free) users get 200 pulls per 6 hours. Authenticated users with a paid subscription get unlimited pulls.

So the quickest fix is to log in before you pull.

docker login
# follow the prompts

Then run your pull or compose command again:

docker pull nginx:latest

If you're in a CI/CD pipeline, set up a Docker Hub account and use credentials as secrets. For GitHub Actions, it looks like this:

steps:
  - name: Log in to Docker Hub
    uses: docker/login-action@v3
    with:
      username: ${{ secrets.DOCKER_USERNAME }}
      password: ${{ secrets.DOCKER_PASSWORD }}
  - name: Pull image
    run: docker pull nginx:latest

That's it. Your rate limit jumps from 100 to 200 pulls per 6 hours. If you still hit the limit with a free account, you either need to wait or upgrade to a Pro/Team plan for unlimited pulls.

Why This Works

The reason step 3 works is that Docker Hub uses the IP address of the requesting client to enforce anonymous rate limits. When you're behind a NAT (common in corporate networks, shared hosting, or cloud CI runners like GitHub Actions or GitLab), your IP is shared with potentially hundreds of other users. Those 100 anonymous pulls evaporate fast.

When you authenticate, Docker Hub associates the pull count with your Docker ID, not the IP. So even if your IP hits the anonymous limit, your authenticated pulls count against your personal 200-pull quota. Free accounts get 200 pulls per 6 hours. Paid accounts get none.

Another subtlety: Docker Hub counts each layer in an image as a separate pull. So pulling a multi-layer image (like python:3.12 with 20+ layers) uses 20+ pulls. That's why you can hit the limit after just a few image pulls.

Less Common Variations of the Same Issue

  • Third-party registries with their own limits — GitHub Container Registry, Quay.io, and GitLab Container Registry each have their own rate limits. GitHub gives 5000 pulls per hour for authenticated users. Quay has 5000 pulls per 12 hours. The same fix applies: log in.
  • Mirror or cache registries — If you run a local Docker registry as a pull-through cache (like registry:2 with proxy.remoteurl), your cache can hit the upstream rate limit. The fix is to authenticate the proxy registry itself. Set REGISTRY_PROXY_USERNAME and REGISTRY_PROXY_PASSWORD environment variables on the cache registry container.
  • Kubernetes pulling from Docker Hub — K8s nodes often share an IP. To avoid rate limits, create a docker-registry secret and reference it in your pod spec:
kubectl create secret docker-registry docker-hub-creds \
  --docker-username=your-username \
  --docker-password=your-password

# In your deployment yaml:
spec:
  imagePullSecrets:
    - name: docker-hub-creds
  • Docker Desktop on corporate VPN — If you're on a VPN, your traffic routes through a corporate egress IP. That IP might be rate-limited by Docker Hub. The fix is still to authenticate. Or use a different registry like mcr.microsoft.com or gcr.io if it's a Microsoft/Google image.

Prevention

Don't wait for the 429 to hit. Make authentication part of your workflow from the start.

  • Always use docker login in your dev environment. Set up Docker Desktop to store credentials. On macOS, it uses the Keychain. On Linux, it uses pass. On Windows, it uses Credential Manager.
  • In CI/CD, use a dedicated Docker Hub account with an access token (not your password). Go to Docker Hub → Account Settings → Security → New Access Token. Use that as the password in your CI secrets.
  • Switch to a private registry if you can. AWS ECR, Azure Container Registry, or Google Artifact Registry don't have per-IP rate limits. They charge per stored data. Your pulls are free.
  • Cache base images locally. On a server or dev machine, pull once and tag it. Subsequent builds reuse the cached layer. That saves pulls.
  • Use a pull-through cache registry for teams. Run a local registry with proxy.remoteurl: https://registry-1.docker.io. All team pulls go through the cache. You pull from Docker Hub once per image version, then the cache serves it locally.

That's it. Log in, pull, move on. The rate limit is a business decision from Docker, not a technical barrier. Work around it with authentication and caching.

Was this solution helpful?