How to fix toomanyrequests: You have reached your pull rate limit in Kubernetes
This error occurs when you exceed Docker Hub's rate limits for image pulls. Fix it by authenticating to increase limits, using registry mirrors, or upgrading to a Docker paid subscription.
Quick fix
Fixes toomanyrequests: You have reached your pull rate limit
# Login locally
docker login
# Check remaining pulls
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull" | jq -r .token)
curl --head -H "Authorization: Bearer $TOKEN" \
https://registry-1.docker.io/v2/library/ubuntu/manifests/latest 2>&1 | grep -i ratelimit- Authenticate to Docker Hub to increase limits
- Create Kubernetes imagePullSecrets for Docker Hub
- Upgrade to Docker Pro or Team subscription
- Set up a Docker registry mirror
# Login locallydocker login# Check remaining pullsTOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull" | jq -r .token)curl --head -H "Authorization: Bearer $TOKEN" \https://registry-1.docker.io/v2/library/ubuntu/manifests/latest 2>&1 | grep -i ratelimittoomanyrequests: You have reached your pull rate limit
What this error means
The "toomanyrequests: You have reached your pull rate limit" error means you've exceeded Docker Hub's rate limiting policy for image pulls. Docker Hub limits anonymous pulls to 100 per 6 hours per IP address, and authenticated free users to 200 per 6 hours. In Kubernetes environments, this error frequently occurs because multiple pods across many nodes share the same egress IP address, rapidly consuming the rate limit. CI/CD pipelines and auto-scaling workloads are particularly susceptible since they pull images frequently during deployments and scaling events. The error manifests as HTTP 429 (Too Many Requests) and causes pods to enter ImagePullBackOff state until the rate limit window resets.
Typical symptoms
- Pods stuck in ImagePullBackOff with 429 error code
- Docker pull fails with "toomanyrequests" message
- Works locally but fails in CI/CD or Kubernetes
- Intermittent failures during high-volume deployments
- All pods on cluster fail to pull simultaneously
- Pulls succeed early in day, fail later (quota exhausted)
Common causes
- Unauthenticated pulls hitting 100/6hr anonymous limit
- Multiple containers pulling from shared IP exhaust quota quickly
- Free Docker account authentication only provides 200/6hr limit
- Shared cloud infrastructure (managed Kubernetes) multiplies pull counts
- Expired or invalid Docker Hub credentials causing unauthenticated fallback
How to fix "toomanyrequests: You have reached your pull rate limit"
Authenticating increases your limit from 100 to 200 pulls per 6 hours:
# Login locally
docker login
# Check remaining pulls
TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:library/ubuntu:pull" | jq -r .token)
curl --head -H "Authorization: Bearer $TOKEN" \
https://registry-1.docker.io/v2/library/ubuntu/manifests/latest 2>&1 | grep -i ratelimitExpected output shows your limits:
RateLimit-Limit: 200
RateLimit-Remaining: 195Add Docker Hub credentials to your cluster:
# Create docker-registry secret
kubectl create secret docker-registry dockerhub-secret \
--docker-server=docker.io \
--docker-username=<YOUR_USERNAME> \
--docker-password=<YOUR_ACCESS_TOKEN> \
--docker-email=<YOUR_EMAIL>
# Patch default ServiceAccount
kubectl patch serviceaccount default -p \
'{"imagePullSecrets": [{"name": "dockerhub-secret"}]}'Apply to deployment:
spec:
template:
spec:
imagePullSecrets:
- name: dockerhub-secret
containers:
- name: app
image: myrepo/myapp:latestNote: Create a Docker access token at hub.docker.com/settings/security—don't use your password.
For unlimited pulls, upgrade your Docker subscription:
- Docker Pro: $9/month per user → unlimited pulls
- Docker Team: $15/month per user → unlimited pulls + team management
- Docker Business: Custom pricing → enterprise features
After upgrading:
# Re-authenticate to apply new limits
docker logout && docker login
# Verify unlimited status
curl -s "https://hub.docker.com/v2/users/<USERNAME>" | jq '.is_paid'Check your account at hub.docker.com/settings/billing.
Deploy a local caching proxy to pull once, serve many times:
# Run official pull-through cache
docker run -d \
-p 5000:5000 \
-e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \
--name registry-proxy \
registry:2
# Configure Docker daemon to use mirror
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["http://localhost:5000"]
}
EOF
# Reload Docker
systemctl reload dockerAlternative: Use Google's free mirror for popular images:
docker pull mirror.gcr.io/library/ubuntu:latest
docker pull mirror.gcr.io/library/nginx:alpineDistribute pulls across multiple accounts:
# GitHub Actions example
name: Build
on: push
jobs:
build-1:
runs-on: ubuntu-latest
steps:
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USER_1 }}
password: ${{ secrets.DOCKERHUB_TOKEN_1 }}
- run: docker build . -t myapp:v1
build-2:
runs-on: ubuntu-latest
steps:
- uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USER_2 }}
password: ${{ secrets.DOCKERHUB_TOKEN_2 }}
- run: docker build . -t myapp:v2This spreads 200 pulls × N accounts across your pipeline.
Minimize image pull frequency:
# Pin specific versions (better caching)
FROM ubuntu:22.04
# NOT this (always re-pulls):
FROM ubuntu:latestUse Docker layer caching in CI:
# GitHub Actions with layer caching
- uses: docker/build-push-action@v4
with:
context: .
cache-from: type=registry,ref=myregistry/myapp:buildcache
cache-to: type=registry,ref=myregistry/myapp:buildcache,mode=maxConsider moving base images to your own registry (ECR, GCR, ACR) where you control rate limits.
Advanced notes
Current Docker Hub Rate Limits (2025):
- Anonymous: 100 pulls/6 hours per IP
- Free authenticated: 200 pulls/6 hours per account
- Docker Pro/Team/Business: Unlimited (fair use policy)
Enterprise Registry Mirrors:
- Nexus Repository (free/OSS): Proxy all registries with 10GB+ caching
- JFrog Artifactory: Multi-region federation, pull-through cache
- Harbor (free/OSS): Air-gapped registries, image scanning, RBAC
Monitoring Rate Limits: Use regctl to check remaining pulls without consuming quota:
regctl image ratelimit nginx:latestKubernetes Node-Level Authentication: Configure containerd to authenticate at the node level in /etc/containerd/config.toml, avoiding per-pod secrets.
Shared IP Consideration: In cloud environments, all pods may share a NAT gateway IP. A single 100-pod deployment can exhaust anonymous limits instantly.
Frequently asked questions
- What does "toomanyrequests: You have reached your pull rate limit" mean?
- The "toomanyrequests: You have reached your pull rate limit" error means you've exceeded Docker Hub's rate limiting policy for image pulls. Docker Hub limits anonymous pulls to 100 per 6 hours per IP address, and authenticated free users to 200 per 6 hours. In Kubernetes environments, this error frequently occurs because multiple pods across many nodes share the same egress IP address, rapidly consuming the rate limit.
- How do I fix "toomanyrequests: You have reached your pull rate limit"?
- This error occurs when you exceed Docker Hub's rate limits for image pulls. Fix it by authenticating to increase limits, using registry mirrors, or upgrading to a Docker paid subscription.
- What causes "toomanyrequests: You have reached your pull rate limit"?
- Unauthenticated pulls hitting 100/6hr anonymous limit Multiple containers pulling from shared IP exhaust quota quickly Free Docker account authentication only provides 200/6hr limit
- Is the "toomanyrequests: You have reached your pull rate limit" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- 📚Kubernetes Official Documentation
- 📖K8s: Images guide(Official Docs)
- 📖Docker Hub: Rate limiting(Official Docs)
- 💬SO: Docker rate limit(Stack Overflow)