Skip to content

Troubleshooting

Scope: the one diagnostic loop that answers most questions, and the half-dozen failure states that account for nearly every stuck pod a beginner meets — what each means and the first check for it.

The loop

Almost every investigation is these four commands, in this order, before anything cleverer:

kubectl get pods                       # what state, how many restarts?
kubectl describe pod <name>            # events, at the bottom: the cluster's own account
kubectl logs <name>                    # the app's account
kubectl logs <name> --previous         # the crashed container's account
kubectl get events --sort-by=.lastTimestamp   # the namespace's recent history

get says what, describe says why the cluster thinks so, logs says what the program said. Skipping describe is the classic beginner waste of an hour: the Events section at its bottom is where scheduling failures, pull failures, and missing-config errors are simply written down.

The states, decoded

State What it means First checks
Pending No node has taken the pod Resources: did it ask for more CPU/RAM than any node has? describe shows FailedScheduling and why
ImagePullBackOff / ErrImagePull The image can't be fetched; backoff = it's retrying, slower each time Typo'd name or tag (the classic); private registry without credentials; no network to the registry
CrashLoopBackOff The container starts, exits, restarts, repeat logs --previous: the app is telling you. Usual causes: bad config, missing file, a dependency it can't reach
CreateContainerConfigError A referenced ConfigMap or Secret (or key in one) doesn't exist Did you apply the ConfigMap first? Does the key name match exactly? (The worked example, applied out of order, lands here on purpose-adjacent)
Running, but 0/1 ready Alive, failing its readiness probe Probe path/port wrong, or the app is up but not actually serving yet
Service answers nothing No endpoints behind the Service kubectl get endpoints <svc>: empty means the selector doesn't match any pod's labels — compare them character by character
Completed Not an error: a run-to-finish container that finished Only a problem if you expected a server

Two habits worth more than any row: read the newest event first (sort helps; stale events from an old failure linger), and change one thing between checks — the states are informative exactly because they're specific.

When it's the cluster, not you

Pods Pending on every node, DNS names failing cluster-wide (hello-web unresolvable from other pods), or images that pulled fine yesterday: suspect the platform layer — a node out of disk (evictions follow), the cluster DNS pods themselves unwell (kubectl get pods -n kube-system), or, on a local cluster, the host machine simply out of memory. kubectl describe node <name> lists the pressure conditions the node itself is reporting. Knowing which layer you're standing in — your object, the node, the control plane — is most of troubleshooting; the loop above is how you find out.