Kubernetes Image Pull Rate Limit / Timeout - Fix in CI
The kubelet hit a registry rate limit or a slow pull timed out. These are transient: the same pod often pulls cleanly minutes later once the limit window resets or the network recovers.
What this error means
Pod events show toomanyrequests: You have reached your pull rate limit or a pull i/o timeout/context deadline exceeded from the registry, then ImagePullBackOff. It is intermittent - a retry frequently succeeds.
Failed to pull image "node:20": toomanyrequests: You have reached your pull
rate limit. https://www.docker.com/increase-rate-limitCommon causes
Anonymous Docker Hub rate limit
Nodes pulling anonymously from Docker Hub share an IP-based quota. On busy clusters/CI that quota is exhausted quickly, returning 429 toomanyrequests.
Slow or congested pull
A large image over a congested link can exceed the runtime’s pull timeout, surfacing as a transient i/o timeout that succeeds on a later attempt.
How to fix it
Authenticate pulls to raise the quota
An authenticated pull is tied to your account, not the shared node IP, and gets a much higher limit.
kubectl create secret docker-registry dockerhub \
--docker-server=https://index.docker.io/v1/ \
--docker-username="$DH_USER" --docker-password="$DH_TOKEN"
# attach via the workload's ServiceAccountMirror or cache base images
- Pull through a registry mirror or your own registry (ECR/GCR/GHCR).
- Pin digests so already-pulled layers are reused across nodes.
- Pre-pull hot images onto nodes (DaemonSet) to avoid per-pod pulls.
Let the kubelet retry the transient failure
Rate-limit and timeout pulls are time-windowed; the kubelet’s built-in back-off retry usually succeeds without intervention.
How to prevent it
- Authenticate all Docker Hub pulls in CI/cluster, even for public images.
- Serve base images from a registry you control or a pull-through cache.
- Pin digests so cached layers are reused.