How to Fix ImagePullBackOff by Reading the Registry Error
ImagePullBackOff is a retry timer, not a cause. Read the registry error in the pod events, match it to the failing layer, and force a clean retry safely.

Quick Answer
A pod shows ImagePullBackOff after the kubelet has failed to pull its container image and is waiting, with a growing delay capped at 300 seconds, before trying again. The status never names the cause. The registry's error string in the pod's Events does, and it separates a missing tag, rejected credentials, a rate limit, an untrusted certificate, a network failure and an architecture mismatch, each with a different fix.
ImagePullBackOff is the Kubernetes status for a container whose image could not be pulled, while the kubelet waits before its next attempt. We treat it the way we treat CrashLoopBackOff, as a symptom that tells you which phase failed and nothing about why.
Most guides answer it with a checklist of every possible cause. We think that wastes the one piece of evidence the cluster already gives you, which is the exact error the registry or the runtime returned.
In this post we cover what the status means, how to read the error string, how to fix ImagePullBackOff for each error, why the pod stays broken after the fix, how the failure's shape points to a layer, and when the string is not enough.
ImagePullBackOff Is a Retry Timer, Not a Root Cause
When a pull fails, the container reports the reason ErrImagePull. After repeated failures it moves to ImagePullBackOff, which means the kubelet is waiting before the next attempt rather than actively failing.
The Kubernetes documentation on images describes the timing plainly. "Kubernetes raises the delay between each attempt until it reaches a compiled-in limit, which is 300 seconds (5 minutes)." The same page gives an invalid image name or a private registry without an imagePullSecret as typical reasons.
So the status tells us two things only. The image was never pulled on that node, and the kubelet will keep retrying. Everything else has to come from the error text.
Read the Error String From the Pod Events
We start every ImagePullBackOff investigation with one command and one line of its output.
kubectl describe pod <pod-name> -n <namespace>
At the bottom, the Events section holds a Warning event with the reason Failed. Its message carries the error returned by the registry or the container runtime, and that message is the diagnosis.
When a pod has been retrying for a while, the events are easier to read in time order.
kubectl get events -n <namespace> --field-selector involvedObject.name=<pod-name> --sort-by=.lastTimestamp
If the event text is truncated or ambiguous, we reproduce the pull on the affected node with crictl pull <image> and read the kubelet log with journalctl -u kubelet. Pulling from a laptop proves much less, because the laptop has different credentials, a different network path and often a different CPU architecture.
How to Fix ImagePullBackOff for Each Registry Error
We map the error string to a layer before changing anything. The table lists the strings we see most often, what each means and the check that confirms it.
| Error string in the event | Layer | What it means | Confirming check |
|---|---|---|---|
manifest unknown or not found |
Image reference | The repository answered, but the tag or digest does not exist | List the repository's tags in the registry |
pull access denied or insufficient_scope |
Image reference or access | The repository is missing, or it is private and the node lacks access | Pull with known-good credentials from the node |
unauthorized or authentication required |
Credentials | Credentials were missing, wrong or expired | Inspect the imagePullSecret and its expiry |
toomanyrequests |
Registry quota | The pull rate limit for this identity or IP was reached | Count recent pulls from the node's egress IP |
x509: certificate signed by unknown authority |
Transport | The node does not trust the registry's TLS certificate | Run curl -v against the registry from the node |
i/o timeout or no such host |
Network | The node cannot resolve or reach the registry | Resolve and connect to the registry from the node |
no match for platform in manifest |
Image build | The image has no variant for the node's CPU architecture | Inspect the image index for the node's platform |
The error codes behind several of these strings come from the OCI distribution specification, which defines codes such as MANIFEST_UNKNOWN, NAME_UNKNOWN, UNAUTHORIZED, DENIED and TOOMANYREQUESTS. Runtimes and registries word their messages differently, so we match on the code or the key phrase rather than the whole sentence.
• Missing Tags and Unknown Manifests
A not-found error on a manifest means the registry knows the repository but not the tag. We check for a typo in the tag, a CI job that failed before pushing, or a tag that a retention policy deleted.
The fix lives in the workload spec or the build pipeline. Credentials and networking are not involved, so rotating secrets here only adds noise.
• Rejected or Expired Credentials
An unauthorized error means the registry wanted credentials and did not accept the ones it got. We first confirm the pod references the right imagePullSecret in the right namespace, then check whether the credential has simply expired.
Expiry is common with short-lived tokens. Amazon's ECR registry authentication guide states that the authorization token is valid for 12 hours, so a secret created once by hand will fail half a day later unless something refreshes it.
• Rate Limits on Public Registries
A toomanyrequests error means a quota, not a broken image. Docker's Docker Hub usage and limits page sets unauthenticated pulls at 100 per IPv4 address or IPv6 /64 subnet over six hours, and authenticated Personal accounts at 200.
Clusters behind one NAT gateway share that address, so a scale-out event can exhaust the quota for every node at once. The durable fixes are authenticated pulls, a pull-through cache or mirror, or moving the images to a registry the team controls.
• Certificate and Network Failures
An x509 error means the node reached the registry and did not trust its certificate, which is common with private registries signed by an internal authority. The node's container runtime needs that authority added, and the image itself is irrelevant.
Timeouts and DNS failures mean the node never reached the registry at all. We check egress rules, proxies and DNS from the node itself, and our guide to the TLS handshake timeout covers the case where the connection opens but the handshake stalls.
• Architecture Mismatches
A platform mismatch means the image was built for one CPU architecture and scheduled onto another, typically an amd64-only image on an arm64 node. The Kubernetes documentation describes image indexes, which let one image name point at architecture-specific variants.
The fix is a multi-architecture build or a node selector that keeps the workload on matching nodes.
Why the Pod Stays Broken After You Fix It
A common frustration is fixing the tag or the secret and watching the pod sit in ImagePullBackOff for several more minutes. The kubelet is honouring its back-off delay, and at the cap it waits up to 300 seconds before it notices anything changed.
We use one of three ways to get a clean retry.
- Delete the pod with
kubectl delete pod <pod-name>, and its controller creates a new one that attempts the pull straight away. - Restart the workload with
kubectl rollout restart deployment <name>, which replaces pods in a controlled order. - Wait, which is the right choice when the cause was a rate limit and hundreds of pods are failing together.
The third option matters more than it looks. Deleting every failing pod at once sends a synchronised burst of pulls at a registry that has just rate-limited you, and that is a small retry storm of your own making.
Read the Failure Shape Before Touching the Manifest
Before reading any single event, we look at how many pods and nodes are affected. The shape of the failure usually narrows the layer faster than the string does.
- One pod, right after a deploy, points to the reference or the pull secret in that manifest.
- Many pods on many nodes at the same timestamp point to the registry, a shared credential rotation or a quota.
- Running pods healthy while new pods fail points to a pull path that broke weeks ago and was hidden by images cached on the node.
- Failures on only some nodes point to a node pool with a different architecture, subnet or egress rule.
The cached-image case is the one that surprises teams most. Under the default IfNotPresent pull policy a node that already holds the image never pulls it again, so expired credentials stay invisible until a node is replaced or the workload scales out.
Many of these strings recur across very different clusters. Browsing root cause analysis run on public GitHub issues is a quick way to see one status hiding several causes in practice. The same evidence-first habit applies to container crashes, which we cover in CrashLoopBackOff triage order.
When the Error String Is Not Enough
The error string is the best first clue, but we do not treat it as proof. A few cases need more than the event text.
A pull access denied message is ambiguous by design, because the same text can mean a missing repository or a private one the node cannot see. We settle it by pulling with known-good credentials from the node, not by rereading the manifest.
Pull-through caches, mirrors and corporate proxies can also rewrite or replace the upstream error. If the event names the mirror rather than the original registry, we check the mirror's own logs before trusting the message.
Finally, a pull that fails once and then succeeds may never have needed a fix. A brief registry or network blip produces a real error string that leads nowhere, which is why we confirm the failure is still happening before changing anything. The same caution applies to exit codes, as we explain in our guide to exit code 137.
Start Every ImagePullBackOff Investigation at the Events
We would make one habit standard on every on-call rota. When a pod shows ImagePullBackOff, read the Failed event, name the layer from the string, confirm it from the node, and only then change a manifest, a secret or a network rule.
That order turns a vague status into a short, evidence-led fix. It is also how Operate approaches an investigation, running self-hosted with read-only access to logs, databases and repositories, citing the evidence behind each finding, and proposing any code fix as a patch file an engineer reviews and applies.
Frequently Asked Questions
ImagePullBackOff means a container could not start because its image could not be pulled, and the kubelet is waiting before retrying. We read it as a timer rather than an error, because the real cause sits in the pod's Failed event, where the registry's message explains what went wrong.
ErrImagePull is the reason recorded when a pull attempt fails. ImagePullBackOff is the waiting state that follows repeated failures, while the kubelet delays the next attempt. We treat both as the same problem and read the same Failed event, because the underlying error is identical.
ImagePullBackOff happens before the container exists, because the image never arrived on the node. CrashLoopBackOff happens after the container starts and then exits repeatedly. We check the image and registry for the first, and the container's logs and exit code for the second.
We delete the pod so its controller creates a fresh one that pulls immediately, or restart the deployment to replace pods in order. If a rate limit caused the failure, we wait instead, because deleting many pods at once can trigger the limit again.
A cluster cannot see images stored in your laptop's Docker daemon, so it tries to pull them from a registry and fails. We either push the image to a registry the cluster can reach or load it into the local cluster's image store, then set a pull policy that does not force a fresh pull.
About the author
Operate Team
The team behind Operate
Operate Team builds Operate, enterprise AI agents for production operations. Operate answers production questions from Slack and Microsoft Teams, investigates alerts, and reviews performance, security and cost. It finds the root cause with evidence and proposes a fix for an engineer to review, with controlled access to your systems.


