ImagePullBackOff, ErrImagePull and registry rate limits
The image cannot be fetched. The message after the status names which of four quite different reasons it is.
What you see
Pods stay pending with ImagePullBackOff, or docker pull fails. Describing the pod gives the real message.
What is actually wrong
A rate limit on anonymous pulls, credentials missing for a private registry, a tag that does not exist, or a TLS interception proxy the node does not trust.
Codes and articles
Fixes (3)
Stop pulling anonymously
A rate limit message.
Confirm the message.
kubectl describe pod mypod | tail -20Anonymous pulls from Docker Hub are limited per IP address, so an entire office or cluster behind one NAT address shares one small quota.
This is why the problem appears suddenly on a cluster that has worked for months — the limit is per source address, not per machine, and one busy pipeline consumes it for everyone.
Authenticate, which raises the limit substantially even on a free account.
kubectl create secret docker-registry dockerhub \ --docker-server=https://index.docker.io/v1/ \ --docker-username=USER --docker-password=TOKEN
Attach it to the service account so every pod uses it without per-pod configuration.
kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"dockerhub"}]}'Better, run a pull-through cache or mirror so images are fetched once for the whole cluster.
kubectl get nodes -o wideSet imagePullPolicy to IfNotPresent for images with fixed tags, so a restart does not pull again.
kubectl get deploy myapp -o jsonpath='{.spec.template.spec.containers[*].imagePullPolicy}'
kubectl get events --sort-by=.lastTimestamp | tail -20Supply credentials the node can actually use
unauthorized, or authentication required.
Check the secret exists in the same namespace as the pod. An imagePullSecret in a different namespace is invisible.
kubectl get secrets -n mynskubectl get pod mypod -n myns -o jsonpath='{.spec.imagePullSecrets}'
Secrets are namespaced and image pull secrets are not shared. This is the most common cause of credentials that are definitely correct and definitely not working.
Check the secret's contents decode to the right registry host.
kubectl get secret regcred -n myns -o jsonpath='{.data.\.dockerconfigjson}' | base64 -dThe registry server must match exactly what the image reference uses, including whether it has a port.
Test the credentials directly from a node.
sudo crictl pull registry.example.com/myapp:1.2.3docker login registry.example.com
Rotate the token if it has expired — most registry tokens are short-lived by design.
kubectl get pod mypod -n myns -wResolve a missing tag or a TLS trust problem
manifest unknown, or an x509 certificate error.
For manifest unknown, check the tag exists and matches the node's architecture.
docker manifest inspect myimage:tag | head -30A tag that exists for amd64 but not arm64 fails exactly like a missing tag on a mixed cluster.
kubectl get nodes -o custom-columns=NAME:.metadata.name,ARCH:.status.nodeInfo.architectureMixed-architecture clusters — a few Raspberry Pi or Graviton nodes alongside x86 — produce this intermittently, on whichever nodes the scheduler happened to choose.
For a certificate error, the node does not trust the registry's issuer, usually because of a TLS inspection proxy.
openssl s_client -connect registry.example.com:443 -servername registry.example.com </dev/null 2>/dev/null | openssl x509 -noout -issuer -subjectInstall the issuing certificate on every node, in the system trust store, and restart the container runtime.
sudo cp corp-root.crt /usr/local/share/ca-certificates/sudo update-ca-certificatessudo systemctl restart containerd
Do not add the registry to insecure-registries as a workaround — it removes certificate verification for that host entirely.
Worth stating plainly because it is the first suggestion in most search results. It turns a trust problem into a permanently unverified connection carrying the images your cluster runs.
sudo crictl pull registry.example.com/myapp:1.2.3Related faults
Where this stops. This write-up was written and checked by hand. It says what each step changes, how to confirm it worked and how to reverse it, and anything destructive is flagged before you reach it. If it does not match what your machine is doing, search the Support Centre for the exact code or message — and when something needs a person, get in touch.