All posts
Muhtalip Dede profile photoMuhtalip Dede · Founder of kprompt

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

ReasonWhat it meansWhat you do
ErrImagePullThe latest pull attempt failedRead the Event message — tag, auth, or network
ImagePullBackOffPulls keep failing; kubelet is backing offSame root cause — do not wait for it to “heal”
CrashLoopBackOffContainer started, then exitedDifferent 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-pull

Natural-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 payments

Fixing 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.