ImagePullBackOff
What causes this
Kubernetes tried to pull a container image and failed. After repeated failures, it backs off (waits longer between retries). The pod stays in ImagePullBackOff status until the issue is resolved. Common causes:
- The image name or tag is wrong (typo, missing tag)
- The image doesn’t exist in the registry
- The registry requires authentication and credentials aren’t configured
- The registry is unreachable (network issue, private registry behind a firewall)
- You’re pulling from Docker Hub and hit the rate limit
Fix 1: Check the exact error
kubectl describe pod my-pod
Scroll to the Events section at the bottom. You’ll see the specific error:
repository does not exist— wrong image namemanifest unknown— wrong tagunauthorized— missing credentialstimeout— network issue
Fix 2: Verify the image exists
# Test if you can pull it manually
docker pull myregistry.com/myimage:v1.2.3
# Check Docker Hub
docker pull nginx:latest
Common mistakes:
- Missing the registry prefix:
myimage:v1vsmyregistry.com/myimage:v1 - Using
:latestwhen nolatesttag exists - Typo in the image name or tag
Fix 3: Add registry credentials
For private registries, create a pull secret:
kubectl create secret docker-registry regcred \
--docker-server=myregistry.com \
--docker-username=myuser \
--docker-password=mypassword \
--docker-email=me@example.com
Then reference it in your pod spec:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: myregistry.com/myimage:v1.2.3
imagePullSecrets:
- name: regcred
For a whole namespace:
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "regcred"}]}'
Fix 4: Docker Hub rate limits
Docker Hub limits anonymous pulls to 100 per 6 hours. If you’re hitting this in CI or a cluster with many nodes:
# Create a secret with your Docker Hub credentials
kubectl create secret docker-registry dockerhub \
--docker-server=https://index.docker.io/v1/ \
--docker-username=yourusername \
--docker-password=yourpassword
Or use a mirror/cache:
# In containerd config, add a mirror
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://your-mirror.example.com"]
Fix 5: Check network connectivity
If the node can’t reach the registry:
# SSH into the node and test
kubectl debug node/my-node -it --image=busybox
# Inside the debug container:
wget -O- https://myregistry.com/v2/
Common network issues:
- Firewall blocking outbound HTTPS (port 443)
- DNS not resolving the registry hostname
- Proxy not configured on the node
Fix 6: Check the image architecture
If you built the image on an ARM Mac but your cluster runs on AMD64:
# Check the image architecture
docker manifest inspect myimage:v1 | grep architecture
Build for the right platform:
docker buildx build --platform linux/amd64 -t myimage:v1 .
Related resources
How to prevent it
- Always use specific image tags (
:v1.2.3) instead of:latest— you’ll know exactly what version should be pulled - Set up
imagePullSecretsat the namespace level so every pod gets credentials automatically - Use a container registry close to your cluster (same cloud provider) to avoid network issues
- In CI, push the image and verify it exists before deploying to Kubernetes
- Set up a registry mirror or cache to avoid Docker Hub rate limits