Fix Kubernetes ImagePullBackOff and ErrImagePull

Quick answer
ImagePullBackOff means Kubernetes can't pull your container image. The real reason is always in the pod events — wrong tag, missing credentials, rate limit, or network issue. Here's how to diagnose and fix each one.
- Step 1: Read the actual error
- Cause 1: Image tag doesn't exist — manifest unknown
- Cause 2: Image name or repository is wrong — not found / repository does not exist
- Cause 3: Private registry — missing or wrong credentials — unauthorized
- Cause 4: Docker Hub rate limit — toomanyrequests
5 min read · Kubernetes
Fix Kubernetes ImagePullBackOff and ErrImagePull
NAME READY STATUS RESTARTS AGE
api-5f9d8 0/1 ImagePullBackOff 0 3m
ErrImagePull is the first failure — the container runtime tried to pull the image and failed. ImagePullBackOff is what follows — Kubernetes is retrying with increasing delays. Both mean the same thing: the image can't be pulled.
The status is vague. The actual error is always in the pod events.
Step 1: Read the actual error
kubectl describe pod <pod-name>Scroll to the Events section at the bottom:
Events:
Warning Failed 2m kubelet Failed to pull image "myapp:v1.2.3": rpc error: code = NotFound desc = failed to pull and unpack image: ... manifest unknown
Warning Failed 2m kubelet Error: ErrImagePull
Warning BackOff 90s kubelet Back-off pulling image "myapp:v1.2.3"
The error message tells you exactly what's wrong. Match it to one of the causes below.
Cause 1: Image tag doesn't exist — manifest unknown
manifest unknown: manifest unknown
The image name is right but the tag doesn't exist in the registry.
1# Verify the exact image and tag you're using
2kubectl get pod <pod-name> -o jsonpath='{.spec.containers[*].image}'
3
4# Check if the tag exists (Docker Hub example)
5docker pull myapp:v1.2.3
6
7# List available tags via registry API (example for Docker Hub)
8curl -s "https://hub.docker.com/v2/repositories/myorg/myapp/tags/" | jq '.results[].name'Fix: Correct the image tag in the Deployment spec. Common mistakes: typo in tag, tag that hasn't been pushed yet, branch name vs semver tag.
Cause 2: Image name or repository is wrong — not found / repository does not exist
failed to pull and unpack image: failed to resolve reference: unexpected status code 404
The repository doesn't exist, or the registry URL is wrong.
# Check the exact image reference
kubectl get deployment <name> -o jsonpath='{.spec.template.spec.containers[*].image}'Fix: Verify the full image path. For private registries the full path matters:
- Docker Hub:
myorg/myapp:tag - ECR:
123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:tag - GHCR:
ghcr.io/myorg/myapp:tag
Cause 3: Private registry — missing or wrong credentials — unauthorized
failed to pull and unpack image: unexpected status code 401 Unauthorized
The image is in a private registry and the node has no credentials.
Fix: Create an imagePullSecret and reference it in the pod spec.
1# For Docker Hub / generic registry
2kubectl create secret docker-registry regcred \
3 --docker-server=https://index.docker.io/v1/ \
4 --docker-username=<username> \
5 --docker-password=<token> # Use access token, not password
6
7# For GitHub Container Registry
8kubectl create secret docker-registry ghcr-cred \
9 --docker-server=ghcr.io \
10 --docker-username=<github-username> \
11 --docker-password=<github-token>
12
13# For AWS ECR — use ECR credential helper or IRSA instead of static tokensReference the secret in the pod:
spec:
imagePullSecrets:
- name: regcred
containers:
- name: api
image: myorg/myapp:v1.2.3Or add it to the namespace's default ServiceAccount so it applies to all pods:
kubectl patch serviceaccount default \
-p '{"imagePullSecrets": [{"name": "regcred"}]}'ECR note: Static ECR tokens expire every 12 hours. Use the ECR credential helper or IRSA with the ecr-token-refresher pattern instead of a static secret.
Stuck on this in production?
We debug exactly this kind of issue for platform teams — usually in a single working session.
Cause 4: Docker Hub rate limit — toomanyrequests
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating.
Docker Hub rate-limits anonymous pulls (100 pulls/6h per IP) and free account pulls (200/6h per account).
Fix options:
- Authenticate pulls — create a Docker Hub imagePullSecret with a logged-in account (200 pulls/6h free, unlimited on paid plans)
- Use a pull-through cache — ECR, GCR, and Harbor can cache Docker Hub images; configure the node's containerd to use it
- Mirror the image — copy to your own registry and reference that instead
Cause 5: Node can't reach the registry — network error
dial tcp: lookup registry.example.com: no such host
context deadline exceeded
The node can't resolve or reach the registry hostname.
# Test DNS and connectivity from inside a pod on the same node
kubectl run debug --image=busybox --rm -it --restart=Never -- sh
nslookup registry.example.com
wget -O- https://registry.example.com/v2/Fix: Check node-level DNS, firewall rules, VPC security groups (for cloud), or proxy settings. In air-gapped environments, you need a local registry mirror.
Quick reference
| Error in events | Cause | Fix |
|---|---|---|
manifest unknown | Tag doesn't exist | Fix the tag |
404 Not Found | Repository doesn't exist | Fix the image name/registry |
401 Unauthorized | Missing credentials | Add imagePullSecrets |
toomanyrequests | Docker Hub rate limit | Authenticate or use a mirror |
dial tcp ... no such host | DNS / network issue | Check node networking |
context deadline exceeded | Registry unreachable | Check firewall / proxy |
See also
- Fix: Kubernetes CrashLoopBackOff — container pulls successfully but keeps crashing
- Fix: Kubernetes Pending Pods — pod never gets scheduled at all
Frequently Asked Questions
How do I tell an authentication failure from a missing image?
The error text distinguishes them. manifest unknown or not found means the reference is wrong — a tag that does not exist or a mistyped repository. unauthorized or denied means the registry rejected your credentials. Describe the pod and read the event rather than guessing.
Why does the image pull locally but not in the cluster?
Usually credentials or architecture. Your laptop is authenticated and the cluster is not, or you built an arm64 image on Apple Silicon and the nodes are amd64. The manifest exists in both cases, which is why the error can be confusing.
How do imagePullSecrets actually get used?
They must be referenced by the pod, either directly or through its ServiceAccount, and must live in the same namespace as the pod. A secret in the wrong namespace or attached to a different ServiceAccount is invisible, which is the most common reason correct credentials still fail.
Why does it keep failing after I fixed the credentials?
Back-off. Kubernetes waits progressively longer between attempts, so a fixed problem can look unfixed for a while. Delete the pod to force an immediate retry rather than waiting for the back-off to elapse.
Official References
- Debug Pods — reading pod status, events and container states
- kubectl reference — command syntax, output formats and selectors
Was this article helpful?
Be the first to rate this article
Related Topics
Found this useful? Share it.


