The Kubernetes error 0/3 nodes are available: 3 Insufficient cpu means the scheduler looked at every node in your cluster and could not fit your pod onto any of them because the CPU it asks for is not available. The 0/3 counts your nodes, and 3 Insufficient cpu says all three failed the same check. Your pod will sit in Pending until something frees CPU or you add capacity.
What this error means
The scheduler places pods based on resources.requests, not on live CPU usage. Every pod that is already running has reserved a slice of each node’s allocatable CPU through its own requests. When the scheduler adds up those committed requests, it finds no node with enough free room to satisfy your pod’s requests.cpu. That is the whole cause of Insufficient cpu.
The point people miss: this is about requests, not utilization. A node can look nearly idle in kubectl top nodes and still be full on requests, so the scheduler treats it as having no room. The exact same pattern produces Insufficient memory when requests.memory is the constraint. The preemption: 0/3 nodes are available line simply means the scheduler could not evict lower priority pods to make space either.
Common causes
- CPU requests are set far higher than the workload actually uses, so each pod reserves more than it needs.
- The cluster genuinely lacks capacity: real demand has grown past the nodes you have.
- No autoscaling is configured, so the node count cannot grow to meet new pods.
- A single pod requests more CPU than any node type in the cluster can offer.
- A recent deploy raised replica count or bumped
requests.cpu, pushing total requests over capacity. - Related but separate blockers can also keep a pod
Pending: node selectors or affinity that match nothing, taints with no matching toleration, or an unbound PVC. The scheduler reports those with different messages, so confirm the event saysInsufficient cpubefore chasing capacity.
How to fix it
Stabilize
- Confirm the pod is the only thing stuck and nothing else is being evicted:
kubectl get pods -o wide
- If this is a production rollout that is now blocked, roll back to the last working revision so traffic keeps flowing while you diagnose:
kubectl rollout undo deployment/<name>
Diagnose
- Read the scheduler events on the pending pod. The
FailedSchedulingevent carries the exact reason:
kubectl describe pod <pod-name>
- Look at how much CPU is already committed versus allocatable on each node. Check the
Allocated resourcessection:
kubectl describe nodes
- Compare committed requests against live usage. A gap here confirms the requests are inflated:
kubectl top nodes
- Read the pod’s own request to see what it is asking for:
kubectl get pod <pod-name> -o yaml
Fix
- If the request is larger than real usage, lower
requests.cputo match measured demand and redeploy:
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
-
If the requests are already right sized and the cluster is simply full, add capacity. Either scale the node group manually or enable the Cluster Autoscaler (or Karpenter) so nodes grow on demand.
-
If one pod needs more CPU than any node provides, move that node group to a larger instance type so a single node can hold the pod.
-
If the block is actually affinity or a taint rather than capacity, correct the misconfigured
nodeSelector, affinity rule, or add the matching toleration.
How to prevent it
- Set
requests.cpufrom measured usage, not guesses. Watch real consumption for a week and size to it. - Enable the Cluster Autoscaler or Karpenter so capacity tracks demand.
- Monitor total cluster requests against allocatable capacity, not just utilization, and alert before you hit the ceiling.
- Use a
LimitRangeper namespace to set sane default requests and stop any single pod from reserving the whole cluster.
When to call a senior engineer
If requests are already right sized, autoscaling is on, and pods still will not schedule, you likely have a capacity planning or node topology problem that needs deeper work. The same is true when preemption, pod priority, and affinity interact in ways that are hard to reason about under incident pressure. Erzon can join mid incident, get the deploy unblocked, and right size the cluster so it does not recur.
Related errors we fix
Want a senior engineer to just fix it?
Paste this exact error into the form. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.
Book a fix