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.
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.
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.
## 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
image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub