On this page
  1. What does it mean when a pod is Pending?
  2. Why is my pod Pending? What are the causes?
  3. How do I diagnose a Pending pod?
  4. How do I fix a Pending pod?
  5. Where AI coding assistants get this wrong
  6. Checklist
  7. FAQ
    1. What does Pending mean on a Kubernetes pod?
    2. Why does my pod say 0/1 nodes are available?
    3. Why is my pod Pending after a fresh install?
    4. How long should a pod stay Pending before I worry?
    5. Is Pending different from CrashLoopBackOff?
    6. Should I set resource requests at all?
  8. Related topics
  9. Sources
concept

Why Is My Kubernetes Pod Stuck Pending?

A Pending pod has not been scheduled onto a node. Learn the causes — resources, taints, selectors, volumes — and how to diagnose each with describe.

Quick answer

  • A pod is Pending when the scheduler has not placed it on a node. It has not started and it has not failed — it has nowhere to run.
  • The reason is always in the pod’s events. Start with kubectl describe pod and read the scheduler’s message.
  • The usual causes are resource requests larger than any node has free, a node selector matching nothing, an untolerated taint, or a volume that will not bind.
  • On a single-node cluster, Pending almost always means your requests exceed the node’s capacity.

What does it mean when a pod is Pending?

Pending is a scheduling state, not a failure. The API server has accepted the pod and it exists, but the scheduler (kube-scheduler) has not found any node it can run on and has not assigned it anywhere. It sits in the queue until something changes — usually a node gaining capacity, or a configuration change.

This is a different failure mode from a crash loop, and the distinction matters because the diagnosis is completely different. A CrashLoopBackOff pod ran and died; the container’s own logs are where the answer is. A Pending pod never ran, so container logs are empty and useless, and the answer is in the scheduler’s events.

Where this bites vibecoders

The specific way this bites vibecoders is a generated manifest with realistic-looking resource numbers and a small server. An assistant writes resources: requests: cpu: 500m, memory: 512Mi because that is a plausible-looking example, and you apply it to a 1GB VPS. The pod is Pending forever, no error is printed, and the obvious conclusion is that Kubernetes is broken. Nothing in the YAML flags that the request exceeds the machine.

Why is my pod Pending? What are the causes?

CauseScheduler messageTypical situation
Insufficient resourcesInsufficient cpu / Insufficient memoryRequests exceed what any node has free
Node selector matches nothingnode(s) didn't match Pod's node affinity/selectorA nodeSelector naming a label your nodes do not carry
Untolerated tainthad untolerated taintA control-plane or dedicated node is excluded
No nodes at allno nodes available to schedule podsCluster empty, or all nodes NotReady
Volume will not bindpod has unbound immediate PersistentVolumeClaimsStorage class missing or PV not yet provisioned
Affinity conflictnode(s) didn't match pod affinity rulesA co-location rule that cannot be satisfied
Node selectors on valuesnode(s) didn't match Pod's node affinity/selectorSelector pinned to a machine type you do not have
Pod priority too lowpreemption: no preemption victims foundA higher-priority pod holds the capacity

Read the whole message. The scheduler lists one reason per node, and the output often contains several different failures at once — a selector problem and insufficient memory. Fixing only the first leaves the pod Pending.

How do I diagnose a Pending pod?

Three commands, in order. The first two are almost always sufficient.

1. Read the events. This is where the answer is:

kubectl describe pod my-app-7d9f8b6c4-x2k9p

Look at the Events: section at the bottom. A Pending pod produces a repeating FailedScheduling entry that names the reason:

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  2m    default-scheduler  0/1 nodes are available: 1 Insufficient cpu.

That single line tells you the node exists, and that the problem is CPU. If the node selector were wrong, the message would say node(s) didn't match Pod's node affinity/selector instead.

2. Compare requests against node capacity. For insufficient resources, check what the pod asked for against what is actually free:

# What the pod requested
kubectl describe pod my-app-7d9f8b6c4-x2k9p | grep -A5 Requests

# What the node has
kubectl describe node | grep -A8 "Allocatable"

Then check what is already claimed:

kubectl top nodes
kubectl describe node | grep -A20 "Allocated resources"

3. Check the node is healthy. If no nodes available appears, the node itself may be the problem:

kubectl get nodes
# STATUS should be Ready, not NotReady
kubectl describe node | grep -i taint

A node stuck NotReady is a separate problem — usually networking or a kubelet failure — and it silently makes every pod Pending.

How do I fix a Pending pod?

Match the fix to the reason, and confirm it by watching the pod leave Pending.

Requests exceed capacity. Lower them, or add capacity. On a small node, the request is a floor, not a suggestion — a pod requesting 1Gi of memory on a node with 800Mi free will never run:

resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    memory: 512Mi

Requests drive scheduling; limits drive runtime enforcement. This distinction is the subject of Kubernetes Requests vs Limits.

Node selector matches nothing. Inspect the labels your nodes actually have, then correct the selector:

kubectl get nodes --show-labels
kubectl get pod my-app -o jsonpath='{.spec.nodeSelector}'

A taint is not tolerated. List the taints, then add a matching toleration to your pod:

kubectl describe node | grep -i taint

A volume will not bind. Check the claim and the storage class:

kubectl get pvc
kubectl get storageclass
kubectl describe pvc my-data | grep -A5 Events

An empty kubectl get storageclass is the usual cause — nothing is configured to provision volumes, and a dynamic provisioning request waits forever. On k3s, the local-path provisioner is usually present; on managed clusters, the default class often is not.

No nodes available. Fix the node before the pod. Check kubectl get nodes, then the kubelet on that machine.

Verify the fix:

kubectl get pod -w

The pod should move to ContainerCreating and then Running. If it stays Pending, the new event message will show a different reason — re-read it rather than assuming the first fix worked.

Where AI coding assistants get this wrong

  • Generating resource requests that exceed a small server’s capacity, because the numbers came from a documentation example rather than your machine.
  • Omitting resources entirely, which avoids Pending but leaves the pod a first target for eviction and the node unprotected.
  • Adding a nodeSelector copied from a cloud-provider tutorial, pinning the pod to labels your nodes do not have.
  • Hardcoding nodeName, which bypasses the scheduler entirely and silently skips resource checks, affinity, and taints — use nodeSelector or affinity.
  • No toleration on a dedicated or control-plane node, so the pod never considers it even when it is the only node available.
  • Assuming Pending means the image is bad. A missing image produces ErrImagePull or ImagePullBackOff, not FailedScheduling — see ImagePullBackOff.
  • Debugging container logs for a pod that has never started, where the logs are necessarily empty.
  • A PVC with no storage class, so the volume stays unbound and the pod waits forever with a misleading message.

Checklist

  • Run kubectl describe pod and read the FailedScheduling event before anything else.
  • Read the entire scheduler message; it usually lists several reasons.
  • Compare requests against the node’s Allocatable values.
  • Check what is already allocated with kubectl describe node | grep -A20 "Allocated resources".
  • Confirm the node is Ready before investigating pod configuration.
  • List actual node labels with kubectl get nodes --show-labels and correct any nodeSelector.
  • Check taints and add a matching toleration where appropriate.
  • Verify a storage class exists before deploying a pod with a PVC.
  • Prefer nodeSelector or affinity over nodeName.
  • Set resource requests deliberately, sized to the machine you actually have.
  • Watch kubectl get pod -w to confirm the pod leaves Pending.

FAQ

What does Pending mean on a Kubernetes pod?

Pending means the pod has been accepted by the API server but the scheduler has not yet placed it on a node. The pod object exists and is not failing — it simply has nowhere to run. The reason is always written in the pod’s events, which is where you should start looking.

Why does my pod say 0/1 nodes are available?

The scheduler tried every node in your cluster and rejected all of them, then summarised the count. The message lists each reason, such as insufficient cpu or memory, a node selector that matches nothing, or an untolerated taint. Read the full message, because the first reason shown is often only one of several.

Why is my pod Pending after a fresh install?

On a single-node cluster the most common cause is a resource request larger than the node has available. A generated manifest that asks for 500m of CPU and 512Mi of memory will sit Pending forever on a 1-vCPU, 1GB VPS. Lower the requests, or size the node to match.

How long should a pod stay Pending before I worry?

If it has been Pending for more than a minute or two, something is wrong — a healthy cluster schedules a pod in well under a second. If the events are only appearing a moment ago, a recent node addition or a scale-up may resolve it on its own.

Is Pending different from CrashLoopBackOff?

Yes, and the distinction directs you to different evidence. Pending means the pod was never scheduled, so the answer is in the scheduler’s events and the node’s capacity. CrashLoopBackOff means the pod ran and the container exited, so the answer is in the container’s logs — see How to Debug a Crash-Looping Container.

Should I set resource requests at all?

Yes, but size them to the machine you have. Requests determine where a pod can be placed, so a request that exceeds any node’s free capacity makes the pod permanently Pending. Omitting requests works but leaves the scheduler blind and makes your pod the first evicted under memory pressure.

Sources

Share: