Fix: ImagePullBackOff and ErrImagePull in Kubernetes
The pod cannot start because the node failed to pull the container image. Read the "Failed to pull image" event to see why: wrong name or tag, missing registry credentials, or no network.
Not checked by a trusted editor yet Last edited Outdated?
The pod never starts, and kubectl get pods shows one of these statuses:
NAME READY STATUS RESTARTS AGE
web-6f7c9d4b8b-k2xpl 0/1 ErrImagePull 0 12s
web-6f7c9d4b8b-k2xpl 0/1 ImagePullBackOff 0 45s
ErrImagePull is the failed attempt; ImagePullBackOff means the kubelet is waiting before trying again. It keeps retrying with a growing delay, up to five minutes between attempts, so a permanent problem never fixes itself.
Find the real reason
kubectl describe pod web-6f7c9d4b8b-k2xpl -n shop
At the bottom, the events show the image and the registry’s answer. The kubelet’s messages have this form:
Normal Pulling kubelet Pulling image "registry.example.com/shop/web:1.4.0"
Warning Failed kubelet Failed to pull image "registry.example.com/shop/web:1.4.0": <reason from the runtime>
Warning Failed kubelet Error: ErrImagePull
Normal BackOff kubelet Back-off pulling image "registry.example.com/shop/web:1.4.0"
Warning Failed kubelet Error: ImagePullBackOff
The text after Failed to pull image ...: comes from the container runtime and the registry, and it tells you which cause below applies.
Cause 1: wrong image name or tag (most common)
Typos, a tag that was never pushed, or a missing registry prefix. The reason usually mentions not found or manifest unknown. A name without a registry means Docker Hub: busybox is short for docker.io/library/busybox:latest.
- Copy the exact image string from the event.
- Check it from a machine that can reach the registry, for example with
docker pull,podman pullorcrane manifest. - Fix the tag in your manifest or Helm values and apply again, or roll back with
kubectl rollout undo deployment/web -n shop.
Cause 2: private registry without credentials
The reason mentions unauthorized, authentication required or pull access denied. Create a registry Secret in the same namespace as the pod and reference it:
kubectl create secret docker-registry regcred -n shop \
--docker-server=registry.example.com \
--docker-username=ci-puller \
--docker-password='CHANGE_ME'
spec:
imagePullSecrets:
- name: regcred
containers:
- name: web
image: registry.example.com/shop/web:1.4.0
Instead of adding it to every pod, you can attach it to the namespace’s service account: kubectl patch serviceaccount default -n shop -p '{"imagePullSecrets":[{"name":"regcred"}]}'. Prefer a read-only pull token over a personal password.
Cause 3: registry rate limits
Docker Hub limits anonymous pulls. The reason then mentions toomanyrequests. Authenticate with a pull secret, use a mirror or pull-through cache, or copy the image into your own registry.
Cause 4: the node cannot reach the registry
Timeouts, connection refused, DNS failures or x509: certificate signed by unknown authority point at the node, not Kubernetes. The pull is done by the container runtime on the node, so proxy settings, firewall rules and trusted CA certificates must be configured there. Test from the node itself, for example with crictl pull.
Cause 5: wrong CPU architecture
An image built only for amd64 cannot run on arm64 nodes. Depending on the runtime, this shows up as a pull error saying no matching manifest exists for the platform, or as a container that starts and immediately fails with exec format error. Build multi-architecture images or add a nodeSelector on kubernetes.io/arch.
Related: InvalidImageName
If the status is InvalidImageName, the image string cannot even be parsed (for example uppercase letters or a stray space). Fix the string; retrying will not help.
After the fix
Once the cause is fixed, a Deployment picks up the corrected manifest automatically. For a pod still backing off with an unchanged spec (for example after you created a missing pull secret), delete the pod so its controller recreates it immediately, or wait for the next retry.
Official documentation
See also
- 0139 Collect describe, events and logs of a failing Kubernetes pod A bash script that saves a pod's status, describe output, events, YAML, current and previous logs of every container and its node… Intermediate · How-to · Linux, macOS Script Troubleshooting 15 Oct 2026
- 0140 kubectl cheat sheet: the commands you use every day A compact reference of everyday kubectl commands: contexts and namespaces, listing and inspecting objects, logs and exec, applying changes, rollouts, scaling and… Beginner · Reference · Any system Article Concepts · Troubleshooting 15 Oct 2026
- 0141 List Kubernetes pods that are not Running and Ready A bash script that lists every pod across namespaces that is Pending, failing or running but not ready, with the waiting reason,… Intermediate · Reference · Linux, macOS Script Troubleshooting 15 Oct 2026
- 0143 Fix: CrashLoopBackOff in Kubernetes The container starts, exits, and Kubernetes waits longer before each restart. Read the previous container's logs and its exit code to find… Intermediate · Fix · Linux Article Troubleshooting 15 Oct 2026
- 0144 Fix: Pod stuck in Pending with “0/3 nodes are available: Insufficient cpu” The scheduler cannot find a node with enough unreserved CPU for the pod's request. Compare the request with node allocatable resources, then… Advanced · Fix · Linux Article Troubleshooting · Workloads & services 15 Oct 2026
- 0145 Fix: OOMKilled (exit code 137) in Kubernetes A container used more memory than its limit and the kernel killed it. Confirm the reason, measure real usage, then raise the… Advanced · Fix · Linux Article Troubleshooting · Workloads & services 15 Oct 2026
Repos in the wild
- derailed/k9s derailed/k9s K9s is a terminal UI for Kubernetes that lets you browse resources, read logs, open shells and follow cluster changes from the keyboard. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Commitpedia +4,054 chars