LimitRange violation: The container's resources fall outside the namespace's permitted range
A LimitRange sets minimum and maximum resources per container or pod in a namespace, and supplies defaults. A pod outside the range is rejected at admission with a message naming the boundary it broke.
Applies to: All Kubernetes versions
What it means
A LimitRange operates per object rather than per namespace total, which is what distinguishes it from a ResourceQuota. It can enforce a minimum request, a maximum limit, a maximum ratio between limit and request, and it can inject defaults into containers that specify nothing. Rejections name the offending value and the boundary — for example maximum memory usage per Container is 1Gi, but limit is 2Gi. The defaulting behaviour is the part that causes confusion, because a container with no resources specified does not stay that way: the LimitRange fills them in, and the resulting pod may then be rejected by a quota, or be scheduled with requests nobody chose deliberately.
Most common causes
- A container requesting more than the maximum the LimitRange allows.
- A container requesting less than the minimum, which is often set to prevent BestEffort pods.
- A limit-to-request ratio exceeding the configured maximum.
- A default injected by the LimitRange producing a value that then violates a ResourceQuota.
- A pod-level total exceeding a pod-scoped maximum even though each container is within the per-container one.
- A LimitRange added to a namespace after workloads were already running, so the next rollout fails.
How to diagnose it
- Read the ranges in force:
kubectl describe limitrange -n NAMESPACE. - Read the rejection message — it names the resource, the boundary, and the offending value.
- Check what a pod actually got after defaulting:
kubectl get pod POD -o jsonpath='{.spec.containers[*].resources}'. This often differs from the manifest. - Check for both a LimitRange and a ResourceQuota in the namespace, since they interact.
- Check whether the LimitRange is new relative to the workload.
How to fix it
- Bring the container's requests and limits inside the permitted range.
- Adjust the LimitRange if the boundary is genuinely wrong for the namespace's workloads.
- Set resources explicitly rather than relying on injected defaults, so what runs is what was intended.
- Split the workload into more, smaller containers if a per-container maximum is the constraint and the work can be divided.
- Move a workload with unusual resource needs into its own namespace with its own LimitRange.
Notes
A LimitRange's defaults apply only to containers that omit a value, so a container specifying a request but not a limit gets a defaulted limit and keeps its own request. This partial defaulting produces resource combinations nobody wrote down, which is worth checking on the running pod rather than assuming from the manifest.
Related
- exceeded quota — The namespace's ResourceQuota rejected the object
- Insufficient cpu — No node has enough CPU for the pod's request
Sources
- Kubernetes documentation — Limit Ranges
- Kubernetes documentation — Resource Quotas
- Kubernetes documentation — Resource Management for Pods and Containers