How to fix toomanyrequests: You have reached your pull rate limit in Docker

DockerBEGINNERMEDIUMUpdated Dec 1, 2025ยท 287 views

The Docker Hub rate limit error occurs when you exceed the allowed number of image pulls. Unauthenticated users are limited to 10 pulls per hour, while authenticated free users get 40 pulls per hour. Fix this by authenticating with Docker Hub, using a registry mirror, or mirroring images to a private registry.

Quick fix

Fixes toomanyrequests: You have reached your pull rate limit

# Get an authentication token (anonymous)
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull" | jq -r .token)

# Check rate limit headers
curl -s -H "Authorization: Bearer $TOKEN" -I https://registry-1.docker.io/v2/library/alpine/manifests/latest 2>&1 | grep -i ratelimit
  1. Check your current rate limit status
  2. Authenticate with Docker Hub
  3. Configure Docker credentials in CI/CD
  4. Use a Docker registry mirror
docker โ€” error
# Get an authentication token (anonymous)
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull" | jq -r .token)
# Check rate limit headers
curl -s -H "Authorization: Bearer $TOKEN" -I https://registry-1.docker.io/v2/library/alpine/manifests/latest 2>&1 | grep -i ratelimit
toomanyrequests: You have reached your pull rate limit

What this error means

When you see "toomanyrequests: You have reached your pull rate limit," Docker Hub is telling you that your IP address or account has exceeded the maximum allowed image pulls within the current time window. Docker Hub implements rate limiting to ensure fair usage across all users and maintain service quality. As of December 2024, the limits are: - **Unauthenticated users**: 10 pulls per hour (60 per 6 hours) - **Authenticated free users**: 40 pulls per hour (240 per 6 hours) - **Docker Pro/Team/Business**: Unlimited pulls The limit is tracked per IPv4 address for anonymous pulls, or per Docker Hub account for authenticated pulls. If you're behind a NAT, proxy, or shared network (like in a CI/CD environment), multiple users may share the same IP and collectively exhaust the limit faster.

Typical symptoms

  • Docker pull commands fail with 'toomanyrequests' error
  • CI/CD pipelines fail during image pull stages
  • Kubernetes pods stuck in ImagePullBackOff state
  • Docker Compose fails to start services requiring image pulls
  • Error message mentions 'You may increase the limit by authenticating'
  • Builds work locally but fail in shared environments

Common causes

  1. Too many anonymous pulls from a shared IP address (NAT/proxy)
  2. CI/CD runners sharing the same external IP address
  3. Kubernetes cluster pulling images frequently without authentication
  4. Running docker pull on images you already have locally (still counts)
  5. Multiple team members on the same network pulling images
  6. Automated builds or tests repeatedly pulling base images

How to fix "toomanyrequests: You have reached your pull rate limit"

1Check your current rate limit status

Before making changes, check how many pulls you have remaining:

bash
# Get an authentication token (anonymous)
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/alpine:pull" | jq -r .token)

# Check rate limit headers
curl -s -H "Authorization: Bearer $TOKEN" -I https://registry-1.docker.io/v2/library/alpine/manifests/latest 2>&1 | grep -i ratelimit

Look for headers like ratelimit-remaining to see how many pulls you have left.

2Authenticate with Docker Hub

The simplest fix is to log in with a Docker Hub account, which increases your limit significantly:

bash
# Log in to Docker Hub
docker login

# Or use an access token (recommended for CI/CD)
docker login -u YOUR_USERNAME -p YOUR_ACCESS_TOKEN

To create an access token:
1. Go to https://hub.docker.com/settings/security
2. Click "New Access Token"
3. Give it a description and select permissions
4. Use the token instead of your password

For CI/CD, store credentials as secrets and use them in your pipeline.

3Configure Docker credentials in CI/CD

GitHub Actions:

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

GitLab CI:

yaml
before_script:
  - echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin

Jenkins:

groovy
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
    sh 'echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin'
}
4Use a Docker registry mirror

Configure Docker to use a public mirror that caches images:

bash
# Edit Docker daemon configuration
sudo nano /etc/docker/daemon.json

Add or modify the registry-mirrors setting:

json
{
  "registry-mirrors": ["https://mirror.gcr.io"]
}

Restart Docker to apply:

bash
sudo systemctl restart docker

Google's mirror.gcr.io is free and doesn't require authentication.

5Set up a pull-through cache with Harbor or Registry

For teams and organizations, set up your own pull-through cache:

Using Docker Registry:

yaml
# docker-compose.yml
version: '3'
services:
  registry:
    image: registry:2
    ports:
      - "5000:5000"
    environment:
      REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io
    volumes:
      - registry-data:/var/lib/registry
volumes:
  registry-data:

Then configure clients to use your cache:

bash
docker pull localhost:5000/library/nginx

The cache pulls from Docker Hub once and serves subsequent requests locally.

6Mirror images to a private registry

Copy frequently used images to your own registry (AWS ECR, GCR, Azure ACR, or self-hosted):

bash
# Pull the image once
docker pull nginx:latest

# Tag for your registry
docker tag nginx:latest your-registry.com/nginx:latest

# Push to your registry
docker push your-registry.com/nginx:latest

Or use skopeo for direct copying without local storage:

bash
skopeo copy docker://docker.io/library/nginx:latest docker://your-registry.com/nginx:latest

Update your Dockerfiles and Kubernetes manifests to use the new image locations.

7Configure Kubernetes ImagePullSecrets

For Kubernetes clusters, create a secret with Docker Hub credentials:

bash
kubectl create secret docker-registry dockerhub-creds \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=YOUR_USERNAME \
  --docker-password=YOUR_TOKEN \
  --docker-email=YOUR_EMAIL

Reference it in your deployments:

yaml
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: app
    image: nginx
  imagePullSecrets:
  - name: dockerhub-creds

Also consider setting imagePullPolicy: IfNotPresent to avoid unnecessary pulls.

Advanced notes

## Understanding Rate Limit Headers

When you make a pull request, Docker Hub returns headers indicating your limit status:
- RateLimit-Limit: Maximum pulls allowed in the window
- RateLimit-Remaining: Pulls remaining in current window
- RateLimit-Reset: Unix timestamp when the window resets (not always present)

## Rate Limits vs Abuse Limits

Docker Hub has two types of limits:
1. Pull Rate Limits: Based on account type, apply to manifest requests
2. Abuse Rate Limits: Apply to all requests (API, web, pulls), based on request volume

If you see rate limiting on non-pull operations, you may be hitting the abuse limit.

## Cost-Effective Solutions

Before paying for Docker Pro/Team:
1. Authenticate - Free accounts get 4x the limit of anonymous
2. Use mirrors - mirror.gcr.io is free and fast
3. Cache locally - Pull-through cache is free to run
4. Use ECR Public - Amazon ECR Public Gallery has many popular images without rate limits

## Enterprise Considerations

For organizations with heavy Docker usage:
- Docker Business provides unlimited pulls and additional features
- AWS ECR, Google Artifact Registry, and Azure ACR have their own (typically higher) limits
- Self-hosted registries like Harbor provide complete control over caching and access

Frequently asked questions

What does "toomanyrequests: You have reached your pull rate limit" mean?
When you see "toomanyrequests: You have reached your pull rate limit," Docker Hub is telling you that your IP address or account has exceeded the maximum allowed image pulls within the current time window. Docker Hub implements rate limiting to ensure fair usage across all users and maintain service quality. As of December 2024, the limits are: - Unauthenticated users: 10 pulls per hour (60 per 6 hours) - Authenticated free users: 40 pulls per hour (240 per 6 hours) - Docker Pro/Team/Business: Unlimited pulls The limit is tracked per IPv4 address for anonymous pulls, or per Docker Hub account for authenticated pulls.
How do I fix "toomanyrequests: You have reached your pull rate limit"?
The Docker Hub rate limit error occurs when you exceed the allowed number of image pulls. Unauthenticated users are limited to 10 pulls per hour, while authenticated free users get 40 pulls per hour. Fix this by authenticating with Docker Hub, using a registry mirror, or mirroring images to a private registry.
What causes "toomanyrequests: You have reached your pull rate limit"?
Too many anonymous pulls from a shared IP address (NAT/proxy) CI/CD runners sharing the same external IP address Kubernetes cluster pulling images frequently without authentication
Is the "toomanyrequests: You have reached your pull rate limit" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading