ImagePullBackOff means Kubernetes tried to pull your container image, failed, and is now retrying with exponential backoff. The pod will never start until the pull succeeds — but the fix is usually one of five causes, and kubectl describe tells you which within seconds.

Table of Contents

  • See the real error
  • Cause 1 — Wrong image name or tag
  • Cause 2 — Private registry auth
  • Cause 3 — Rate limits and network
  • Cause 4 — Platform/architecture mismatch
  • Cause 5 — Tag exists but was overwritten
  • When it's actually ErrImagePull

See the real error

Don't guess — get the event:

kubectl describe pod <pod-name> -n <namespace> 

Scroll to Events at the bottom. The Failed to pull image line carries the real reason verbatim:

Failed to pull image "myregistry/app:v2": rpc error: code = NotFound desc = failed to pull and unpack image: failed to resolve reference: myregistry/app:v2: not found 

Each cause below maps to a distinct event message.

Cause 1 — Wrong image name or tag

Event says: not found, manifest unknown, or does not exist.

The image name or tag doesn't exist in the registry. Check for typos first — ngnix vs nginx is embarrassingly common — then verify the tag actually exists:

# For Docker Hub, check the tag exists crane ls myrepo/myimage # or check the registry UI docker pull myregistry/app:v2 # test the pull from your machine 

Watch for latest — it only exists if someone pushed it, and on some registries it means nothing at all. Pin explicit tags in the manifest.

Cause 2 — Private registry auth

Event says: unauthorized, 401, access denied, no basic auth credentials.

Kubernetes can't authenticate to your registry. Fix: create an image pull secret and reference it:

kubectl create secret docker-registry regcred \ --docker-server=myregistry.example.com \ --docker-username=robot_user \ --docker-password=<token> \ -n my-namespace 
spec: imagePullSecrets: - name: regcred containers: - name: app image: myregistry.example.com/app:v2 

For ECR/GCR/ACR, prefer workload identity or node-level IAM over static secrets — cloud registries rotate tokens. Gotcha: the secret must be in the same namespace as the pod, and default service accounts can carry it cluster-wide via imagePullSecrets on the SA.

Cause 3 — Rate limits and network

Event says: toomanyrequests, connection refused, i/o timeout, context deadline exceeded.

  • Docker Hub rate limits — anonymous pulls are capped per IP; a busy cluster NATs all pulls through one egress IP and hits the ceiling fast. Fix: authenticate pulls (higher limit) or mirror images to your own registry.
  • Corporate proxy/firewall — nodes can't reach the registry. Test from a node: crictl pull <image> bypasses Kubernetes entirely.
  • DNS — lookup myregistry on 10.96.0.10:53: no such host means CoreDNS can't resolve it; check kube-dns pods.

Cause 4 — Platform/architecture mismatch

Event says: no matching manifest for linux/arm64 (or amd64).

The image was built for the wrong CPU architecture — common when developers build on Apple Silicon and deploy to amd64 nodes. Fix: build multi-arch images:

docker buildx build --platform linux/amd64,linux/arm64 \ -t myregistry/app:v2 --push . 

Cause 5 — Tag exists but was overwritten

Event says: pull succeeds but the container is wrong, or pull used to work and silently changed.

Someone repushed the tag with different content. imagePullPolicy: Always pulls every restart; IfNotPresent caches whatever it first pulled — a moving latest tag gives different nodes different images. Pin digests for reproducibility:

image: myregistry/app@sha256:abc123... 

When it's actually ErrImagePull

ErrImagePull is the initial failure state; ImagePullBackOff is the retry state — same root causes. If the pod later shows CreateContainerConfigError or CrashLoopBackOff, the pull succeeded and your problem moved elsewhere — see Fixing CrashLoopBackOff for the next tier of debugging.

The one-line summary: describe the pod, read the event, fix the named cause. ImagePullBackOff is never the disease — it's the symptom.

Related Articles

Author: CloudOpsGuide Team