EKS
Kubernetes
Pod Scheduling
FailedScheduling
Troubleshooting

Pod creation in EKS cluster fails with FailedScheduling error

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

FailedScheduling means the Kubernetes scheduler looked at the cluster and could not find any node that satisfies the Pod's constraints. In EKS, the root cause is usually not "EKS is broken." It is usually a mismatch between the Pod requirements and the node group, labels, taints, available resources, or autoscaling state.

Start with the scheduler events

The first command should be:

bash
kubectl describe pod <pod-name> -n <namespace>

Look at the events section near the bottom. That usually tells you exactly why scheduling failed, for example:

  • insufficient CPU
  • insufficient memory
  • node affinity mismatch
  • untolerated taint
  • no nodes available
  • persistent volume topology mismatch

Without that event text, you are guessing.

Check resource requests first

One of the most common causes is that the Pod requests more CPU or memory than any current node can offer.

Example:

yaml
1resources:
2  requests:
3    cpu: "4"
4    memory: "16Gi"

If your node group consists of smaller instances, the Pod has nowhere to go.

Check the cluster nodes:

bash
kubectl get nodes
kubectl describe node <node-name>

Then compare the node allocatable resources with the Pod's requests. Remember that scheduling is based on requested resources, not on what the container currently uses at runtime.

Inspect selectors, affinity, taints, and tolerations

A Pod can also exclude itself from every node through scheduling constraints.

Node selector example:

yaml
nodeSelector:
  workload: gpu

If no node in EKS has label workload=gpu, scheduling fails.

Taint and toleration example:

yaml
1tolerations:
2  - key: "dedicated"
3    operator: "Equal"
4    value: "batch"
5    effect: "NoSchedule"

If nodes are tainted and the Pod does not tolerate them, the scheduler will refuse placement even when CPU and memory are available.

So check both sides:

bash
kubectl get nodes --show-labels
kubectl describe node <node-name>

That shows the labels and taints the scheduler is evaluating.

Verify autoscaling and capacity providers

In EKS, a Pending Pod sometimes means the scheduler is correct and the cluster simply needs more nodes. That only helps if autoscaling is installed and configured to react to the unschedulable Pod.

Typical questions:

  • Is Cluster Autoscaler or Karpenter installed?
  • Does it manage the node group that should host this Pod?
  • Can it launch an instance type large enough for the requested resources?

If autoscaling is missing or constrained to small instance types, the Pod will stay pending with FailedScheduling even though scaling would theoretically solve the problem.

Watch for storage and topology constraints

Not every scheduling failure is about CPU or memory. Volumes can block scheduling too.

For example, if a Pod needs a volume that is restricted to a specific availability zone, but the matching nodes are not available in that zone, the scheduler may reject the Pod.

This is especially relevant in EKS because:

  • node groups can span zones
  • EBS volumes are zonal
  • storage classes may use topology-aware provisioning

If the events mention volume binding or topology, inspect the PVC, storage class, and node zones together rather than only looking at Pod resources.

A practical debugging sequence

Use this order:

  1. kubectl describe pod <pod-name> -n <namespace>
  2. read the exact FailedScheduling event
  3. inspect node resources and labels
  4. inspect Pod requests, selectors, tolerations, and affinity
  5. verify autoscaler or Karpenter behavior
  6. check PVC and topology constraints if volumes are involved

This is faster than trying random manifest changes until the Pod happens to schedule.

Common Pitfalls

The biggest mistake is checking only actual node usage and ignoring resource requests. The scheduler uses requested resources, not whatever top says is currently free.

Another common issue is forgetting that one bad selector or missing toleration can eliminate every node in the cluster instantly.

People also assume autoscaling will save them automatically. It only works if it is installed, has permission to act, and can provision a compatible node type.

Finally, storage-related scheduling failures are easy to miss because the Pod error still looks like a general scheduling problem.

Summary

  • 'FailedScheduling means no current node satisfies the Pod's requirements.'
  • Start with kubectl describe pod and read the scheduler events carefully.
  • Check resource requests, node labels, taints, tolerations, and affinity rules.
  • Verify that Cluster Autoscaler or Karpenter can actually create compatible nodes.
  • Do not forget PVC and availability-zone topology when storage is involved.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.