How to fix toomanyrequests: You have reached your pull rate limit in Docker
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- Check your current rate limit status
- Authenticate with Docker Hub
- Configure Docker credentials in CI/CD
- Use a Docker registry mirror
# 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 headerscurl -s -H "Authorization: Bearer $TOKEN" -I https://registry-1.docker.io/v2/library/alpine/manifests/latest 2>&1 | grep -i ratelimittoomanyrequests: 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
- 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
- Running docker pull on images you already have locally (still counts)
- Multiple team members on the same network pulling images
- Automated builds or tests repeatedly pulling base images
How to fix "toomanyrequests: You have reached your pull rate limit"
Before making changes, check how many pulls you have remaining:
# 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 ratelimitLook for headers like ratelimit-remaining to see how many pulls you have left.
The simplest fix is to log in with a Docker Hub account, which increases your limit significantly:
# Log in to Docker Hub
docker login
# Or use an access token (recommended for CI/CD)
docker login -u YOUR_USERNAME -p YOUR_ACCESS_TOKENTo 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.
GitHub Actions:
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}GitLab CI:
before_script:
- echo "$DOCKERHUB_TOKEN" | docker login -u "$DOCKERHUB_USERNAME" --password-stdinJenkins:
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh 'echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin'
}Configure Docker to use a public mirror that caches images:
# Edit Docker daemon configuration
sudo nano /etc/docker/daemon.jsonAdd or modify the registry-mirrors setting:
{
"registry-mirrors": ["https://mirror.gcr.io"]
}Restart Docker to apply:
sudo systemctl restart dockerGoogle's mirror.gcr.io is free and doesn't require authentication.
For teams and organizations, set up your own pull-through cache:
Using Docker Registry:
# 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:
docker pull localhost:5000/library/nginxThe cache pulls from Docker Hub once and serves subsequent requests locally.
Copy frequently used images to your own registry (AWS ECR, GCR, Azure ACR, or self-hosted):
# 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:latestOr use skopeo for direct copying without local storage:
skopeo copy docker://docker.io/library/nginx:latest docker://your-registry.com/nginx:latestUpdate your Dockerfiles and Kubernetes manifests to use the new image locations.
For Kubernetes clusters, create a secret with Docker Hub credentials:
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_EMAILReference it in your deployments:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: nginx
imagePullSecrets:
- name: dockerhub-credsAlso 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
- ๐Docker Official Documentation
- ๐Docker Hub Download Rate Limit Documentation(Official Docs)
- ๐Docker Hub Usage and Limits(Official Docs)
- ๐Understanding Your Docker Hub Rate Limit(Official Docs)
- ๐ฌStack Overflow - Docker Rate Limit Solutions(Stack Overflow)
- ๐