# Kubernetes pod stuck in ImagePullBackOff or ErrImagePull
The kubelet cannot pull the image, so the container never starts. ErrImagePull is the first failure and ImagePullBackOff is the wait between retries — neither says why. The registry's own error text, printed in the pod's Events, is what identifies the cause.
| Error | ImagePullBackOff |
|---|---|
| Applies to | Kubernetes 1.20 and later · kubelet 1.20 and later |
| Primary cause | The image reference is wrong or the tag does not exist |
| First check | kubectl describe pod <pod-name> -n <namespace> |
| Confidence | high4 sources, 4 primary |
| Verified | 2026-08-07fresh0d old · recheck by 2026-12-05 |
| Domain | kuberneteskubernetes kubelet images registry imagepullbackoff troubleshooting |
## Error
ImagePullBackOffCodes: ImagePullBackOffErrImagePull
Also seen as: Back-off pulling image · Failed to pull image · ErrImagePull kubernetes · manifest unknown · pull access denied
## Problem
A pod never reaches Running. Its status alternates between ErrImagePull and ImagePullBackOff, and the restart interval grows. kubectl logs returns nothing because no container was ever created — the failure happens before the image becomes a container, so the usual log-reading reflex gives you nothing to work with.
## Root Cause5 known causes, ranked
- 01
The image reference is wrong or the tag does not exist
primaryA typo in the repository, a tag that was never pushed, or a tag that has since been deleted or overwritten. The registry answers correctly; the reference is simply wrong.
→ how to tell: Events show 'manifest unknown' or 'not found', and pulling the exact same reference from your own machine fails identically
- 02
The registry is private and credentials are missing or wrong
commonNo imagePullSecrets on the pod or its ServiceAccount, a secret in the wrong namespace, or credentials that have expired. Image pull secrets are namespaced, so one that works in staging does nothing in production.
→ how to tell: Events show '401 Unauthorized', 'pull access denied' or 'authentication required'
- 03
The registry rate-limited the pull
commonDocker Hub limits unauthenticated pulls to 100 per IPv4 address or IPv6 /64 subnet per six hours. A cluster behind one NAT address shares that budget across every node, so a busy cluster exhausts it without any single workload looking unusual.
→ how to tell: Events contain 'toomanyrequests' or 'You have reached your pull rate limit'
- 04
The node cannot reach the registry
commonDNS failure, an egress firewall, a proxy that needs configuring on the container runtime rather than the pod, or a private registry with no route from the node subnet.
→ how to tell: Events show 'dial tcp ... i/o timeout', 'no such host' or a TLS handshake failure
- 05
The image has no build for the node's architecture
edgeAn amd64-only image scheduled onto an arm64 node. The reference resolves and credentials work, but the manifest list has no matching entry.
→ how to tell: Events show 'no matching manifest for linux/arm64' or a similar platform string
## Solution
- 01Read the Events at the bottom of the pod description. The registry's own error text is there, and it names the cause; the pod status never does.
$ kubectl describe pod <pod-name> -n <namespace>note: Look for the Failed event from the kubelet — it quotes the runtime's message verbatim.
- 02Reproduce the pull from outside the cluster with the exact same reference. This separates a wrong reference from a cluster-side problem in one step.
$ crane manifest <registry>/<repo>:<tag> || docker pull <registry>/<repo>:<tag> - 03If the registry is private, create a pull secret and attach it to the pod in the same namespace as the pod.bash
kubectl create secret docker-registry regcred \ --docker-server=<registry> \ --docker-username=<user> \ --docker-password=<password> \ -n <namespace>note: Then reference it under spec.imagePullSecrets, or attach it to the ServiceAccount so every pod in the namespace inherits it.
- 04Wire the secret into the pod spec, or the kubelet will keep pulling anonymously.yaml
spec: imagePullSecrets: - name: regcred containers: - name: app image: <registry>/<repo>:<tag> - 05If the message mentions rate limiting, authenticate rather than retry. Unauthenticated pulls share a per-IP budget across the whole cluster, so retrying makes it worse. Mirroring hot images into your own registry removes the dependency entirely.
- 06Fix the reference or the credentials, then replace the pod. Editing nothing and waiting does not help — the kubelet retries with the same failing spec, backing off up to five minutes between attempts.
$ kubectl rollout restart deployment/<name> -n <namespace>
verify · kubectl describe pod shows a 'Successfully pulled image' event and the pod reaches Running; kubectl get pod reports a stable RESTARTS count.
if that fails · Where the registry is genuinely unreachable from the cluster — an air-gapped environment, for example — pre-load the image onto the nodes and set imagePullPolicy to IfNotPresent so the kubelet uses the local copy.
## Applies To
- Kubernetes
- 1.20 and later— ImagePullBackOff is a Waiting-state reason surfaced by the kubelet, not a Pod phase.
- kubelet
- 1.20 and later— Pull retry delay grows to a compiled-in ceiling of 300 seconds.
- Runtimes
- containerd, CRI-O
- Platforms
- linux/amd64, linux/arm64
## Not Applicable Tonear misses this page does not answer
- ✗ CrashLoopBackOff, where the image pulled successfully and the container starts then exits
- ✗ CreateContainerConfigError, where a referenced ConfigMap or Secret is missing
- ✗ ErrImageNeverPull, which means imagePullPolicy is Never and the image is absent from the node
- ✗ Pods stuck in Pending, which is a scheduling problem and never reaches the pull stage
## Evidence4 sources
https://kubernetes.io/docs/concepts/containers/images/
The Kubernetes Authors · read 2026-08-07
supports: The definition of ImagePullBackOff, that an invalid image name and a private registry without an imagePullSecret are its named causes, and that the retry delay grows to a compiled-in ceiling of 300 seconds.
“The status ImagePullBackOff means that a container could not start because Kubernetes could not pull a container image ... which is 300 seconds (5 minutes)”
https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
The Kubernetes Authors · read 2026-08-07
supports: That a docker-registry Secret is the mechanism for authenticated pulls and that it is referenced from the pod through imagePullSecrets.
“Create a Secret by providing credentials on the command line”
https://docs.docker.com/docker-hub/usage/pulls/
Docker Inc. · read 2026-08-07
supports: The unauthenticated pull ceiling of 100 per IPv4 address or IPv6 /64 subnet per six hours, which is why a NATed cluster exhausts the budget collectively.
“Unauthenticated and Docker Personal users are subject to a 6-hour pull rate limit on Docker Hub.”
https://kubernetes.io/docs/tasks/debug/debug-application/debug-pods/
The Kubernetes Authors · read 2026-08-07
supports: That describing the pod and reading its recent events is the first diagnostic step, which is where the registry's own error text appears.
“The first step in debugging a Pod is taking a look at it. Check the current state of the Pod and recent events”
## Confidence
highThe status definition, the retry ceiling and the named causes come from Kubernetes' own image documentation, and the pull-limit figures from Docker's published table. The per-cause discriminators are the runtime's own error strings as surfaced in pod events rather than claims any single document makes about diagnosis.