Fix ‘0/3 nodes are available: insufficient cpu’ Fast in Kubernetes – Complete Troubleshooting Guide
The Monday Morning Kubernetes Crisis
Picture this: It’s Monday morning, your team just pushed a critical microservice update to production, and suddenly your Slack is buzzing with alerts. The new pods aren’t starting, and when you run kubectl get pods, you see the dreaded Pending status. A quick kubectl describe pod reveals the frustrating message:
Events:
Warning FailedScheduling 2m default-scheduler 0/3 nodes are available: insufficient cpu
Sound familiar? You’re not alone. The insufficient cpu kubernetes error is one of the most common scheduling failures DevOps engineers encounter when managing Kubernetes clusters. This comprehensive guide will walk you through understanding, debugging, and permanently fixing this issue.
🚀 Quick Fix Cheatsheet (For the Impatient)

Need a fast solution? Try these in order:
| Problem | Quick Command | Expected Result |
|---|---|---|
| Check pod requirements | kubectl get pod <pod> -o yaml | grep -A 5 "requests:" | See if CPU requests are too high |
| Reduce CPU requests | Edit deployment YAML: cpu: "100m" instead of cpu: "2000m" | Pod should schedule |
| Check node capacity | kubectl describe nodes | grep -A 5 "Allocatable" | Find nodes with available CPU |
| Scale cluster | Add more nodes via cloud provider console | More scheduling targets |
🚨 EMERGENCY PATCH (Use with Caution!)
⚠️ IMMEDIATE CPU FIX – TEMPORARY ONLY
| Command | Warning |
|---|---|
bash<br>kubectl patch deployment <deployment-name> -p \<br>'{"spec":{"template":{"spec":{"containers":[{"name":"<container-name>","resources":{"requests":{"cpu":"50m"}}}]}}}}' | ⚠️ This drastically reduces CPU requests to get pods running immediately. Not a production fix — always reset proper resource requests/limits once the crisis is resolved. |
Quick Commands for Immediate Diagnosis:
# 1. Check what's failing
kubectl get pods | grep Pending
# 2. See the exact error
kubectl describe pod <failing-pod-name>
# 3. Check node resources
kubectl describe nodes | grep -A 5 "Allocated resources"
What Does “0/3 nodes are available: insufficient cpu” Actually Mean?
When Kubernetes displays this error, it’s telling you that the scheduler has examined all available nodes in your cluster and determined that none of them have enough allocatable CPU resources to satisfy your pod’s requirements. This is a scheduling failure, not a runtime error – your application isn’t running because Kubernetes can’t find a suitable place to run it.
See how runtimes affect scheduling in Docker vs Containerd
📊 Kubernetes Scheduling Flow Diagram

The Kubernetes scheduler considers several factors when placing pods:
- CPU requests vs. available capacity
- Memory requests vs. available capacity
- Node taints and tolerations
- Pod affinity and anti-affinity rules
- Resource quotas and limits
In this case, the scheduler specifically identified CPU as the blocking resource across all three nodes in your cluster.
🚨 Common Mistakes That Cause CPU Scheduling Failures
| 🚨 Mistake | ❌ Wrong | ✅ Correct |
|---|---|---|
| 1. Confusing CPU Requests with CPU Limits | Setting requests = limits → wastes resources | Use requests for scheduling, limits for safety |
| 2. Copy-pasting resource configs | “This DB needs 4 cores, so will my API” | Profile your app’s actual CPU usage |
| 3. Ignoring usage vs. requests | “Node shows 30% usage, why no scheduling?” | Check allocated requests, not actual usage |
Quick Reality Check: If your web API is requesting more than 1 CPU core, you probably need to profile your application’s actual resource usage. Most APIs need 100-500m CPU.
Official Kubernetes Docs – Managing Resources for Containers
Step-by-Step Debugging: Identifying the Root Cause
Step 1: Examine the Failed Pod
Start by getting detailed information about the pod that’s failing to schedule:
kubectl describe pod <your-pod-name>
Look for the Events section at the bottom. You’ll typically see something like:
Events:
Type Reason Message
---- ------ -------
Warning FailedScheduling 0/3 nodes are available: insufficient cpu
This confirms you’re dealing with kubernetes insufficient resources specifically related to CPU.
Step 2: Check Your Pod’s Resource Requirements
Examine your pod’s resource requests and limits:
kubectl get pod <pod-name> -o yaml | grep -A 10 resources:
You might see output like:
resources:
requests:
cpu: "2000m" # Requesting 2 CPU cores
memory: "4Gi"
limits:
cpu: "4000m"
memory: "8Gi"
🔍 Pro Tip: If you’re unfamiliar with the YAML structure or want to understand all available resource options, use:
kubectl explain pod.spec.containers.resources
kubectl explain pod.spec.containers.resources.requests
kubectl explain pod.spec.containers.resources.limits
This will show you the exact field structure and available options for resource configuration.
Step 3: Analyze Node Capacity and Availability
Check your cluster’s overall node status:
kubectl get nodes -o wide
Then examine each node’s capacity and current allocations:
kubectl describe node <node-name>
Pay attention to the “Capacity” and “Allocatable” sections:
Capacity:
cpu: 4
memory: 16Gi
Allocatable:
cpu: 3800m
memory: 14Gi
Allocated resources:
cpu: 3200m (84%)
memory: 12Gi (85%)
Step 4: Monitor Real-Time Resource Usage (Critical Distinction!)
Use the metrics server to check actual CPU utilization:
kubectl top nodes
This shows you the real-time CPU and memory usage:
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
worker-node-1 2100m 55% 8Gi 60%
worker-node-2 3100m 81% 11Gi 78%
worker-node-3 2900m 76% 10Gi 71%
⚠️ Critical Understanding: The kubectl top command shows actual CPU usage, but Kubernetes scheduling decisions are based on CPU requests, not actual usage. A node might show only 30% CPU utilization but still be “full” from a scheduling perspective if existing pods have requested 100% of the available CPU through their resource requests.
Example of the Disconnect:
- Node has 4 CPU cores (4000m)
- Actual usage: 1200m (30%)
- Requested by all pods: 3800m (95%)
- Result: New pod requesting 500m will fail to schedule despite low actual usage!
📋 Common Causes vs Fixes Reference Table
| Cause | Symptoms | Quick Fix | Long-term Solution |
|---|---|---|---|
| Pod requests too high | Single pod needs 4+ cores | Lower CPU requests to 100-500m | Profile app to find real requirements |
| Cluster overcommitted | Many small pods failing | Add more nodes | Implement cluster autoscaling |
| Resource misconfiguration | Inconsistent scheduling | Standardize resource templates | Create resource guidelines |
| Node constraints | Pods avoid certain nodes | Remove taints/adjust affinity | Review node labeling strategy |
| Quota limits hit | Namespace-specific failures | Increase quotas temporarily | Review and adjust quota policies |
| No cluster autoscaling | Manual scaling needed | Add nodes manually | Configure autoscaling (managed K8s) |
Common Causes of Insufficient CPU Errors
1. Pod Requests Exceed Node Capacity
Your pod might be requesting more CPU than any single node can provide. For example, requesting 5 CPU cores on nodes that only have 4 cores total.
2. Cluster Overcommitment
Even if nodes have physical capacity, the kubernetes cpu requests limits system might have already allocated the available CPU to existing pods through resource requests.
3. Misconfigured Resource Requests
Developers sometimes set unrealistically high CPU requests (like requesting 8 cores for a simple API service), causing unnecessary pod scheduling failed issues.
4. Node Taints and Affinity Rules
Pods might be restricted from scheduling on certain nodes due to taints, tolerations, or affinity rules, reducing the available scheduling targets.
5. Resource Quotas and Limits
Namespace-level resource quotas might prevent new pods from being scheduled even when nodes have available capacity.
Proven Solutions with Real Examples
Solution 1: Optimize CPU Requests and Limits
The most common fix involves adjusting your pod’s resource configuration. Here’s a before and after example:
Before (Problematic Configuration):
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
spec:
replicas: 3
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api
image: myapp:latest
resources:
requests:
cpu: "2000m" # Too high for most APIs
memory: "4Gi"
limits:
cpu: "4000m"
memory: "8Gi"
After (Optimized Configuration):
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-service
spec:
replicas: 3
selector:
matchLabels:
app: api-service
template:
metadata:
labels:
app: api-service
spec:
containers:
- name: api
image: myapp:latest
resources:
requests:
cpu: "250m" # More realistic for most APIs
memory: "512Mi"
limits:
cpu: "500m" # Allow bursting when needed
memory: "1Gi"
Solution 2: Add More Nodes or Upgrade Existing Ones
If your workload genuinely needs more resources, scale your cluster:
For Managed Kubernetes (EKS, GKE, AKS):
# Using cloud provider CLI tools
# AWS EKS
aws eks update-nodegroup --cluster-name my-cluster --nodegroup-name workers --scaling-config minSize=3,maxSize=10,desiredSize=5
# Google GKE
gcloud container clusters resize my-cluster --num-nodes=5 --zone=us-central1-a
# Azure AKS
az aks scale --resource-group myResourceGroup --name myCluster --node-count 5
For Self-Managed Clusters:
# Add nodes manually
kubectl apply -f new-node-config.yaml
⚠️ Important: Cluster autoscaling features are provider-specific and only available with managed Kubernetes services. If you’re running self-managed Kubernetes, you’ll need to implement custom scaling solutions or manually add nodes.
Solution 3: Implement Horizontal Pod Autoscaling
Instead of requesting more CPU per pod, distribute the load across more pods:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Solution 4: Configure Node Affinity and Anti-Affinity
If certain nodes should be preferred or avoided:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- high-cpu
containers:
- name: app
image: myapp:latest
resources:
requests:
cpu: "1000m"
Solution 5: Use Priority Classes for Critical Workloads
Ensure critical pods can preempt less important ones:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000
globalDefault: false
description: "High priority class for critical applications"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: critical-service
spec:
template:
spec:
priorityClassName: high-priority
containers:
- name: app
image: critical-app:latest
resources:
requests:
cpu: "500m"
Advanced Troubleshooting Techniques
Monitoring Resource Usage Trends
Set up monitoring to understand your actual resource utilization patterns:
# Check historical CPU usage
kubectl top pods --sort-by=cpu
# Monitor specific namespaces
kubectl top pods -n production --sort-by=cpu
Using Resource Quotas Effectively
Implement namespace-level resource management:
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: development
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
persistentvolumeclaims: "4"
Debugging with Cluster Events
Get a broader view of cluster-wide scheduling issues:
kubectl get events --sort-by=.metadata.creationTimestamp
Prevention Strategies: Avoiding Future CPU Issues
1. Implement Proper Resource Monitoring
Use tools like Prometheus and Grafana to monitor resource usage patterns and set up alerts before you hit capacity limits.
2. Establish Resource Request Guidelines
Create team guidelines for setting appropriate CPU requests:
- Web APIs: 100-500m CPU
- Background workers: 200-1000m CPU
- Data processing: 1000m+ CPU
- Databases: 1000-4000m CPU
3. Regular Capacity Planning
Schedule monthly reviews of cluster capacity vs. demand trends to proactively scale your infrastructure.
4. Use Cluster Autoscaling
Configure cluster autoscaling to automatically add nodes when resource pressure increases:
For Managed Kubernetes Services:
# Example for AWS EKS - Cluster Autoscaler configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-autoscaler-status
namespace: kube-system
data:
nodes.max: "20"
nodes.min: "3"
scale-down-enabled: "true"
scale-down-delay-after-add: "10m"
Cloud Provider Examples:
- AWS EKS: Use AWS Auto Scaling Groups with cluster-autoscaler
- Google GKE: Enable node auto-provisioning in cluster settings
- Azure AKS: Configure virtual machine scale sets with cluster autoscaler
⚠️ Note: Cluster autoscaling is primarily available for managed Kubernetes services. For self-managed clusters, you’ll need custom solutions like KEDA or manual node management.
5. Configure Pod Disruption Budgets
Prevent resource conflicts during maintenance and node scaling by defining how many pods can be unavailable:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-service-pdb
spec:
minAvailable: 2 # Always keep at least 2 pods running
selector:
matchLabels:
app: api-service
---
# Alternative: specify maximum unavailable
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker-pdb
spec:
maxUnavailable: 1 # Allow only 1 pod to be unavailable
selector:
matchLabels:
app: background-worker
Why This Helps: PodDisruptionBudgets ensure that during cluster scaling events or node maintenance, you don’t accidentally evict too many pods and create resource pressure elsewhere in the cluster.
Frequently Asked Questions
Can I run pods without setting CPU requests?
Yes, but it’s not recommended for production. Pods without CPU requests have no scheduling guarantees and may be placed on overloaded nodes. They also have the lowest priority during resource contention and may be evicted first.
Why does my pod show “insufficient cpu” when kubectl top nodes shows low CPU usage?
The scheduler bases decisions on requested resources, not actual usage. Even if nodes are using only 30% CPU, they might have 90% of their CPU already “reserved” through resource requests from existing pods.
How do I calculate the right CPU request for my application?
Start with conservative estimates (100-250m for most web apps), deploy to a test environment, and monitor actual usage with kubectl top pods. Set requests to about 80% of your average usage and limits to handle peak loads.
What happens if I set CPU requests too high?
Your pods may fail to schedule even when nodes have available CPU. This leads to pod scheduling failed errors and poor cluster utilization. It’s better to start low and scale up based on monitoring data.
Can I change CPU requests for running pods?
No, you cannot modify resource requests for running pods. You need to update your Deployment, DaemonSet, or other controller, which will create new pods with the updated configuration and terminate the old ones.
Should CPU requests equal CPU limits?
Not usually. Setting requests equal to limits (called “Guaranteed” QoS class) ensures predictable performance but reduces cluster efficiency. Most applications benefit from setting requests lower than limits to allow bursting during peak usage.
How do I temporarily bypass scheduling constraints for urgent deployments?
Use priority classes to ensure critical pods can preempt lower-priority ones, or temporarily reduce resource requests for non-critical workloads to free up scheduling capacity.
What’s the difference between millicores (m) and full CPU cores?
Kubernetes measures CPU in millicores where 1000m = 1 full CPU core. So 500m = 0.5 cores, 250m = 0.25 cores. This allows for precise resource allocation even for lightweight applications.
How can I prevent this error in CI/CD pipelines?
Implement resource validation in your deployment pipeline, use dry-run deployments (kubectl apply --dry-run=server), and maintain staging environments that mirror production resource constraints.
Conclusion
The insufficient cpu kubernetes error doesn’t have to derail your deployments. By understanding how Kubernetes scheduling works, properly configuring resource requests and limits, and implementing proactive monitoring, you can eliminate this issue from your production environment.
Remember these key takeaways:
- Always set realistic CPU requests based on actual usage patterns
- Monitor your cluster capacity and plan for growth
- Use horizontal scaling instead of just vertical scaling
- Implement proper resource quotas and priority classes
- Keep your resource configurations under version control
The next time you see “0/3 nodes are available: insufficient cpu,” you’ll have the tools and knowledge to quickly diagnose and resolve the issue, keeping your applications running smoothly.
Need more Kubernetes troubleshooting guides? Subscribe to our newsletter for weekly DevOps tips and real-world solutions to common infrastructure challenges.
Related crash scenario troubleshooting:
- Kubernetes CrashLoopBackOff Fix: Proven & Complete Guide
- Kubernetes ImagePullBackOff Fix: Stop Costly Pod Failures Fast
- Fix Kubernetes OOMKilled Fast: Ultimate DevOps Survival Guide
- Fix Kubernetes etcdserver: no leader Error Fast & Easy
- Stop Kubernetes CreateContainerConfigError Nightmares
