Kubernetes
9 min readJuly 2, 2026Updated August 19, 2026

Fix Kubernetes FailedScheduling: 0/N nodes are available

AJ
Ajeet Yadav
Platform & Cloud Engineer
Fix Kubernetes FailedScheduling: 0/N nodes are available

Quick answer

A Pod stuck Pending with FailedScheduling means the scheduler looked at every node and rejected all of them. The Events line tells you why — here's how to read it and fix each cause.

9 min read · Kubernetes

Fix Kubernetes FailedScheduling: 0/N nodes are available

You deploy something, it never comes up, and kubectl get pods shows it stuck in Pending. When you look closer, the Events have a FailedScheduling warning that reads something like 0/5 nodes are available.

This means the scheduler evaluated every node in the cluster and rejected all of them. The good news: the message almost always tells you exactly why. You just need to read it carefully.


What this error means

The Kubernetes scheduler has one job — find a node that satisfies every constraint on your Pod, then bind the Pod to it. If no node passes, the Pod stays Pending and the scheduler records a FailedScheduling event with a per-reason breakdown:

0/5 nodes are available: 3 Insufficient cpu, 2 node(s) had untolerated taint {role: gpu}.

The numbers in front of each reason add up to your total node count. Your job is to figure out which reason blocks the nodes you actually want, and remove that constraint — either on the Pod or on the nodes.


Step 1: See the actual error

Start with the Pod's events. This is where the scheduler writes its verdict.

bash
kubectl describe pod <pod-name>

Look at the Events section at the bottom:

Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  25s (x4 over 2m)    default-scheduler  0/5 nodes are available: 3 Insufficient memory, 2 node(s) had untolerated taint {dedicated: db}.

Then get the lay of the land — how many nodes exist and how loaded they are:

bash
kubectl get nodes
kubectl describe node <node-name>    # look at Allocatable vs Allocated resources

The bottom of describe node shows the Allocated resources table — the sum of all Pod requests already on that node. Compare it to Allocatable (total minus system reserved). If Allocated cpu/memory is near Allocatable, that node is full.


Cause 1: Insufficient cpu or memory

The most common cause. The reason reads Insufficient cpu or Insufficient memory. Either your Pod's requests are too high for any single node, or the cluster is genuinely full.

Scheduling is based on requests, not actual usage — a node with idle CPU can still reject a Pod if the sum of existing requests leaves no room for your request.

Fix — lower the request if it's oversized:

yaml
resources:
  requests:
    cpu: "250m"      # not "4" unless the app truly needs 4 cores
    memory: "256Mi"

Fix — add capacity if the cluster is full. Scale the node group manually, or let autoscaling do it:

bash
# Manually scale a managed node group (example: EKS)
eksctl scale nodegroup --cluster my-cluster --name workers --nodes 5

For hands-off scaling, run Cluster Autoscaler or Karpenter so new nodes are provisioned when Pods go Pending for lack of resources. Karpenter in particular reads the pending Pod's requests and launches a right-sized node within seconds.


Cause 2: node(s) had untolerated taint

The reason reads node(s) had untolerated taint {key: value}. Those nodes are tainted, and your Pod doesn't tolerate the taint, so the scheduler skips them. This is common with GPU pools, dedicated database nodes, and control-plane nodes.

Check the taints:

bash
kubectl describe node <node-name> | grep -i taint
# Taints: dedicated=db:NoSchedule

Fix — add a matching toleration if the Pod belongs on those nodes:

yaml
tolerations:
  - key: "dedicated"
    operator: "Equal"
    value: "db"
    effect: "NoSchedule"

Fix — remove the taint if it shouldn't be there:

bash
kubectl taint nodes <node-name> dedicated=db:NoSchedule-   # trailing - removes it

Cause 3: nodeSelector or nodeAffinity mismatch

The reason reads node(s) didn't match Pod's node affinity/selector. Your Pod requires a label that no schedulable node carries.

Check what your Pod asks for versus what nodes actually have:

bash
kubectl get pod <pod-name> -o jsonpath='{.spec.nodeSelector}'
kubectl get nodes --show-labels

Fix — correct the selector to match a real label, or label the node so it qualifies:

bash
kubectl label node <node-name> disktype=ssd

A frequent trap is a typo or stale value in requiredDuringSchedulingIgnoredDuringExecution — a required nodeAffinity is hard, so a single wrong value blocks scheduling entirely. If the preference is soft, use preferredDuringScheduling... instead so the scheduler falls back rather than failing.


Stuck on this in production?

We debug exactly this kind of issue for platform teams — usually in a single working session.

Talk to us

Cause 4: podAntiAffinity or topology spread can't be satisfied

The reason mentions node(s) didn't match pod anti-affinity rules or node(s) didn't match pod topology spread constraints. You've told Kubernetes to spread replicas apart, but there aren't enough distinct nodes or zones to honor the rule.

For example, a requiredDuringScheduling podAntiAffinity that forbids two replicas on the same node needs at least as many nodes as replicas. A topologySpreadConstraints with whenUnsatisfiable: DoNotSchedule and maxSkew: 1 will block Pods once the skew would be exceeded.

Fix — add nodes/zones, or relax the constraint so it's a preference:

yaml
1topologySpreadConstraints:
2  - maxSkew: 1
3    topologyKey: topology.kubernetes.io/zone
4    whenUnsatisfiable: ScheduleAnyway    # was DoNotSchedule
5    labelSelector:
6      matchLabels:
7        app: api

ScheduleAnyway keeps the spread as a best-effort goal without leaving Pods Pending.


Cause 5: volume node or zone affinity conflict

The reason reads node(s) had volume node affinity conflict. The Pod uses a PersistentVolume that lives in one availability zone, but the only schedulable nodes are in a different zone. EBS and most cloud block-storage volumes are zonal — a Pod bound to a zone-a volume can only run on a zone-a node.

Check where the PV is pinned:

bash
kubectl get pv <pv-name> -o yaml | grep -A5 nodeAffinity

Fix — the cleanest long-term answer is to use a StorageClass with volumeBindingMode: WaitForFirstConsumer, so the volume is created in the same zone the Pod lands in:

yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer

For an existing stuck Pod, make sure you have a schedulable node in the volume's zone.


Cause 6: too many pods on the node

The reason reads Too many pods. Each node has a max-pods cap (default 110, often lower on smaller instances), and on AWS VPC CNI the real limit is IP addresses per node — every Pod needs a routable IP, and small instance types have very few.

bash
kubectl describe node <node-name> | grep -i pods
# Capacity:    pods: 29
# Allocatable: pods: 29

Fix — add nodes, choose larger instance types that support more pods/IPs, or enable prefix delegation on the VPC CNI to multiply the IPs per node:

bash
kubectl set env ds aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true

Quick reference

bash
# The three commands that solve almost every FailedScheduling
kubectl describe pod <name>        # read the FailedScheduling reason
kubectl get nodes --show-labels    # confirm labels for selector/affinity
kubectl describe node <name>       # Allocatable vs Allocated, taints, pod cap
Reason in EventsRoot causeFirst fix
Insufficient cpu / memoryRequests too high or cluster fullLower requests or add nodes
had untolerated taintNode taint, no tolerationAdd toleration or remove taint
didn't match node affinity/selectorLabel mismatchFix selector or label the node
didn't match pod topology spreadNot enough nodes/zonesRelax to ScheduleAnyway
volume node affinity conflictPV in another zoneWaitForFirstConsumer StorageClass
Too many podsmax-pods / IP exhaustionBigger nodes or prefix delegation

Frequently Asked Questions

Why is my Pod Pending when kubectl top nodes shows free CPU?

Because the scheduler counts requests, not live usage. A node can be 10% utilized yet reject your Pod if the sum of all Pod requests already reserves nearly all Allocatable CPU. Right-size your requests to the workload's real needs so the scheduler's math matches reality.

What's the difference between FailedScheduling and a Pending Pod?

Pending is the Pod phase — it hasn't been bound to a node yet. FailedScheduling is the reason it's still Pending: the scheduler tried and failed. A Pod can also be Pending because an init container or image pull is in progress, which is not a scheduling failure at all.

How do I read "0/5 nodes are available" quickly?

Read the reasons after the colon and note that the counts sum to your node total. If one reason covers all nodes, that single constraint is your whole problem. If several reasons split the nodes, you must clear every reason blocking the specific nodes you want the Pod to land on.

Can Cluster Autoscaler fix FailedScheduling automatically?

Only when the reason is a lack of resources. Cluster Autoscaler and Karpenter watch for Pods that are Pending due to insufficient cpu/memory and add nodes. They will not help with taints, affinity mismatches, or volume zone conflicts — those are constraints you have to correct on the Pod or node.

Why does my Pod schedule fine but a StatefulSet replica stays Pending?

Usually a volume zone conflict or a topology spread rule. StatefulSets bind each replica to its own PersistentVolume, and if that PV lives in a zone with no free node, the replica can't schedule. Using a WaitForFirstConsumer StorageClass avoids pinning the volume before the Pod is placed.


See also

Stuck on a scheduling failure that doesn't match any of these? Talk to us at Coding Protocols — we run production Kubernetes clusters and can get your workloads scheduling reliably.

Official References

Was this article helpful?

Be the first to rate this article

Related Topics

Kubernetes
Troubleshooting
Scheduling
Debugging
DevOps

Found this useful? Share it.

Practice this

Related tools

Read Next