Insufficient memory: No node has enough unreserved memory for the pod's request
The same reservation arithmetic as insufficient CPU, applied to memory — but with higher stakes, because memory is not compressible and getting the request wrong risks eviction rather than slowdown.
Applies to: All Kubernetes versions
What it means
The scheduler sums the memory requests already committed on each node and rejects any node where this pod's request would not fit within allocatable memory. Actual memory usage is not consulted. The difference from CPU is what happens when the estimate is wrong in the other direction: a container that needs more CPU than it requested is throttled and continues, while a container that needs more memory than the node can supply is either OOM-killed or evicted. That asymmetry is why memory requests deserve more care than CPU requests, and why under-requesting memory is a genuinely risky way to fit more onto a cluster.
Most common causes
- Memory requests set far above real usage across many workloads.
- A pod requesting more memory than any node has allocatable.
- Nodes fully committed, even while actual usage is low.
- Large kubelet and system reservations reducing allocatable memory below the node's nominal size.
- DaemonSet memory requests consuming a share of every node.
- A LimitRange defaulting memory requests higher than needed.
How to diagnose it
- Read the scheduling failure:
kubectl describe pod POD. - Compare committed requests against allocatable:
kubectl describe node NODE. - Compare requests against measured usage:
kubectl top pods --sort-by=memory. - Check the largest node's allocatable memory against the pod's request.
- Check whether allocatable is much lower than capacity, which indicates large reservations.
How to fix it
- Right-size requests from measured usage, with headroom for peaks rather than for guesses.
- Add nodes or use larger node types when requests are already accurate.
- Set requests and limits equal for workloads that must not be evicted — that gives the pod
GuaranteedQoS and the strongest protection under node pressure. - Reduce inflated defaults from a LimitRange.
- Review DaemonSet requests, which are charged against every node.
Notes
Setting memory request equal to memory limit puts a pod in the Guaranteed QoS class, which is evicted last under node pressure. For anything whose restart is expensive — a database, a cache with a long warm-up — that is usually worth the reduced packing efficiency.
Related
- Insufficient cpu — No node has enough unreserved CPU
- MemoryPressure — The node is low on available memory
Sources
- Kubernetes documentation — Resource Management for Pods and Containers
- Kubernetes documentation — Quality of Service for Pods
- Kubernetes documentation — Kubernetes Scheduler