Insufficient cpu: No node has enough unreserved CPU for the pod's request
This scheduling message compares the pod's CPU request against what each node has left after existing requests — not against actual CPU usage. A node can be nearly idle and still reject the pod.
Applies to: All Kubernetes versions
What it means
The scheduler places pods based on requests, which are reservations, not on current utilisation. Insufficient cpu means the sum of CPU requests already committed on a node plus this pod's request would exceed the node's allocatable CPU. This is why a cluster showing 20 percent CPU utilisation can be unable to schedule anything: every workload requested far more than it uses, and the capacity is reserved even while idle. The gap between requests and usage is the single most common cause of a cluster that appears empty and behaves as if it is full.
Most common causes
- Requests set much higher than actual usage, reserving capacity that is never used.
- A pod requesting more CPU than any single node has allocatable.
- Nodes genuinely full of committed requests.
- DaemonSets and system pods consuming a share of every node's allocatable capacity.
- Node allocatable being lower than node capacity because of kubelet and system reservations.
- A LimitRange defaulting requests to values higher than the workload needs.
How to diagnose it
- Read the scheduler's message:
kubectl describe pod PODshows how many nodes failed for this reason. - Compare requests to allocatable on a node:
kubectl describe node NODEshows both under Allocated resources. - Compare requests to real usage:
kubectl top podsagainst the requests in the specs. A large gap is the usual finding. - Check the largest node's allocatable CPU against the pod's request — if the request exceeds it, no amount of scaling out will help.
- Check for a LimitRange supplying defaults:
kubectl describe limitrange -n NAMESPACE.
How to fix it
- Right-size requests based on measured usage. This usually frees more capacity than adding nodes.
- Add nodes, or larger nodes, if requests are already accurate.
- Split a workload that cannot fit on any single node, or use a node type large enough for it.
- Reduce defaults in a LimitRange if they are inflating every pod's reservation.
- Review DaemonSet requests, since they are multiplied by every node in the cluster.
Notes
CPU is compressible: a container exceeding its CPU limit is throttled rather than killed. That makes CPU requests safer to set close to real usage than memory requests, where under-requesting risks eviction instead of slowdown.
Related
- Insufficient memory — No node has enough unreserved memory
- FailedScheduling — The scheduler could not find a suitable node
Sources
- Kubernetes documentation — Resource Management for Pods and Containers
- Kubernetes documentation — Kubernetes Scheduler
- Kubernetes documentation — Reserve Compute Resources for System Daemons