Portal | Level: L1: Foundations | Topics: Docker / Containers, Kubernetes Core | Domain: Kubernetes
Runbook: ImagePullBackOff¶
Symptoms¶
- Pod status shows
ImagePullBackOfforErrImagePull - Pod never starts
- Events show "Failed to pull image"
Fast Triage¶
kubectl get pods -n grokdevops
kubectl describe pod -n grokdevops -l app.kubernetes.io/name=grokdevops | grep -A5 Events
kubectl get deployment grokdevops -n grokdevops -o jsonpath='{.spec.template.spec.containers[0].image}'
Likely Causes (ranked)¶
- Wrong image tag — typo or nonexistent version
- Image not imported into k3s — local images need
docker save | sudo k3s ctr images import - - Private registry without credentials — missing
imagePullSecrets - Registry unreachable — network or DNS issue
Evidence Interpretation¶
What bad looks like:
- RESTARTS=0 — the container never started, so there is nothing to restart. - ErrImagePull appears first; Kubernetes then backs off exponentially and the status flips to ImagePullBackOff. - Because the container never ran,kubectl logs returns nothing — this is expected, not a second problem.
- Check Events with kubectl describe pod for the exact pull error (e.g., "manifest unknown", "unauthorized").
Fix Steps¶
[!WARNING] In k3s,
docker buildimages are invisible to the cluster. You must explicitly import them withdocker save <image> | sudo k3s ctr images import -before they can be pulled. This is the most common cause of ImagePullBackOff in local dev.
- Check the image name/tag in the deployment
- For k3s local dev:
- For registry auth issues:
- Fix Helm values and redeploy:
Verification¶
kubectl get pods -n grokdevops # STATUS=Running
kubectl describe pod -n grokdevops -l app.kubernetes.io/name=grokdevops | grep "Successfully pulled"
Cleanup¶
None needed beyond fixing the image reference.
Unknown Unknowns¶
imagePullPolicy: Alwaysforces a registry pull even if the image exists locally — change toIfNotPresentfor local dev with k3s.- k3s uses its own image store; a
docker buildimage is invisible to k3s until you rundocker save | sudo k3s ctr images import -. - Private registries need an
imagePullSecretsentry on the Pod spec — or attach the secret to the ServiceAccount so every pod in the namespace inherits it. - The backoff timer doubles each retry (10s → 20s → 40s … up to 5 min), so deleting the pod is faster than waiting during debugging.
Pitfalls¶
- Checking logs — there are none; the container never started. Don't chase a logging problem that doesn't exist.
- Deleting pods — the Deployment will recreate them with the same bad image. Fix the image reference first.
- Not verifying the image exists in the registry — always confirm with
docker manifest inspector the registry UI before assuming a cluster-side issue.
See Also¶
training/library/guides/troubleshooting.mdtraining/interactive/runtime-labs/lab-runtime-05-helm-upgrade-rollback/(bad image tag scenario)training/interactive/incidents/scenarios/imagepull-bad-tag.sh
Wiki Navigation¶
Related Content¶
- Case Study: ImagePullBackOff Registry Auth (Case Study, L1) — Docker / Containers, Kubernetes Core
- Mental Models (Core Concepts) (Topic Pack, L0) — Docker / Containers, Kubernetes Core
- Ops Archaeology: The Deploy That Didn't Deploy (Case Study, L1) — Docker / Containers, Kubernetes Core
- AWS ECS (Topic Pack, L2) — Docker / Containers
- Adversarial Interview Gauntlet (30 sequences) (Scenario, L2) — Kubernetes Core
- Case Study: Alert Storm — Flapping Health Checks (Case Study, L2) — Kubernetes Core
- Case Study: CI Pipeline Fails — Docker Layer Cache Corruption (Case Study, L2) — Docker / Containers
- Case Study: Canary Deploy Routing to Wrong Backend — Ingress Misconfigured (Case Study, L2) — Kubernetes Core
- Case Study: Container Vuln Scanner False Positive Blocks Deploy (Case Study, L2) — Docker / Containers
- Case Study: CrashLoopBackOff No Logs (Case Study, L1) — Kubernetes Core