Kubernetes ImagePullBackOff: how to read ErrImagePull and fix the image reference
ImagePullBackOff means the container never started. How ErrImagePull differs from CrashLoopBackOff, what Events tell you, common causes (bad tag, private registry, rate limit), and how to fix it without guessing.
ImagePullBackOff is the failure that looks like a crash loop until you read one field carefully: the container never started. There are no application logs. There is no exit code from your process. The kubelet tried to pull an image, failed, and is now waiting longer between attempts.
This guide is the operator ladder for pull failures: how ErrImagePull and ImagePullBackOff differ, what Events actually say, the five causes that cover most incidents, and how to fix the image reference — by hand or with a reviewable plan.
ErrImagePull vs ImagePullBackOff
| Reason | What it means | What you do |
|---|---|---|
| ErrImagePull | The latest pull attempt failed | Read the Event message — tag, auth, or network |
| ImagePullBackOff | Pulls keep failing; kubelet is backing off | Same root cause — do not wait for it to “heal” |
| CrashLoopBackOff | Container started, then exited | Different ladder — logs and exit codes matter |
If you run kubectl logs and see nothing useful, that is expected here. The container was never created. Look at Events and the Waiting reason instead of --previous.
Confirm it in 30 seconds
Status, then Events
kubectl get pods -n payments
# NAME READY STATUS RESTARTS
# worker-7d9f4c8b9-xk2m1 0/1 ImagePullBackOff 0
kubectl describe pod -l app=worker -n payments
# Events:
# Failed Failed to pull image "ghcr.io/...:9.9.9": ...
# Failed Error: ErrImagePull
# BackOff Back-off pulling image "ghcr.io/...:9.9.9"- READY 0/1 and RESTARTS 0 — the process never ran
- Waiting reason ImagePullBackOff or ErrImagePull on the container
- Event message names the image reference and often the registry error
- kubectl logs will be empty or “container not found” — that is a clue, not a dead end
The five causes that cover most pull failures
1. Wrong image name or tag
Typo in the repository, a tag that was never pushed, or :latest pointing somewhere unexpected. The Event usually says “not found” or “manifest unknown.” Fix the Deployment image field — do not delete the Pod and hope.
2. Private registry without credentials
The image exists, but the node cannot authenticate. You need an imagePullSecret on the Pod (or a service account that references one), and the Secret must match the registry host. ErrImagePull messages often mention unauthorized or denied.
Check pull secrets on the Pod
kubectl get pod -l app=worker -n payments \
-o jsonpath='{.items[0].spec.imagePullSecrets[*].name}{"\n"}'
kubectl get deploy worker -n payments \
-o jsonpath='{.spec.template.spec.containers[*].image}{"\n"}'3. Registry rate limit
Anonymous Docker Hub pulls still surprise teams on busy CI days. Events mention rate limit or toomanyrequests. Authenticated pulls or a mirror/cache fix the symptom; pinning digests and using your own registry fixes the habit.
4. Network / DNS / firewall to the registry
The cluster cannot reach the registry host — corporate proxy, missing egress, broken CoreDNS, or a wrong mirror. Nodes that pull fine from one registry and fail on another are a network story, not an image story.
5. Architecture mismatch
An arm64-only image on an amd64 node (or the reverse) fails at pull or create time depending on the runtime. Multi-arch manifests or matching node pools fix it. The Event may mention no matching manifest for the platform.
Reproduce it on purpose
kprompt-examples ships an ImagePullBackOff fixture: the worker Deployment points at a tag that does not exist. The container never runs — a good analysis must not invent log lines.
kind cluster, missing image tag
git clone https://github.com/kprompt/kprompt-examples.git
cd kprompt-examples
make up && make break SCENARIO=02-image-pull && make verify
kubectl describe pod -l app=worker -n payments
make fix SCENARIO=02-image-pullNatural-language explain
kprompt's explain path walks Deployments → Pods → Events. For ImagePullBackOff it should name the bad image reference and stop short of claiming it read application logs — because there are none.
Explain is read-only
kprompt "explain why worker is not ready" -n payments
kprompt "why is worker ImagePullBackOff" -n payments
kprompt "describe worker" -n paymentsFixing the image is a mutation: patch the Deployment image or imagePullSecrets, show a plan, then approve. That boundary matters — models guess tags; you still verify the registry.
A corrected image you review first
$ kprompt "set worker image to ghcr.io/example/worker:1.2.3" -n payments
Plan
1. patch Deployment/worker container image → ghcr.io/example/worker:1.2.3
Risk: medium
Apply? [y/N]What not to do
- Do not delete the Pod on a loop — the Deployment recreates the same bad image
- Do not treat empty logs as “the app is silent” — the app never started
- Do not raise memory or CPU for a pull failure
- Do not confuse this with CrashLoopBackOff — different evidence, different fix
- Do not approve an AI-suggested image tag you have not verified in the registry
Related reading
For containers that start and then die, see the CrashLoopBackOff guide. For memory kills, see OOMKilled. For a prompt catalogue across failure modes, see the error prompt playbook.
Related posts
Kubernetes CrashLoopBackOff: how to read it, find the cause, and fix it
CrashLoopBackOff is a symptom, not a cause. How the restart backoff works, what exit codes tell you, the kubectl ladder for finding the real failure, and how to apply a bounded fix you actually reviewed.
Read articleKubernetes OOMKilled: how to detect memory kills, raise limits, and avoid guesswork
A practical guide to OOMKilled in Kubernetes — exit 137, Last State, memory requests vs limits, kubectl checks, and how kprompt explain can suggest a reviewable memory patch.
Read articleHow to troubleshoot Kubernetes: deployments, pods, and crash loops from the terminal
A practical guide to Kubernetes troubleshooting — CrashLoopBackOff, deployments not ready, image pull errors, and rollbacks — using kubectl workflows and natural-language explains with kprompt.
Read article