| title | Kubernetes FailedScheduling | |||||
|---|---|---|---|---|---|---|
| slug | kubernetes-failedscheduling | |||||
| technologies |
|
|||||
| severity | high | |||||
| tags |
|
|||||
| related |
|
|||||
| last_reviewed | 2026-06-27 |
NAME READY STATUS RESTARTS AGE
ingest-7f5d8c6b4d-h9xqv 0/1 Pending 0 4m2s
Warning FailedScheduling default-scheduler 0/12 nodes are available:
3 Insufficient cpu, 4 Insufficient memory,
3 node(s) had untolerated taint {dedicated: gpu},
2 node(s) didn't match Pod's node affinity/selector.
preemption: 0/12 nodes are available: 12 No preemption victims found.
FailedScheduling is emitted by the kube-scheduler when it cannot find any node
that satisfies all of a pending pod's constraints. The pod stays in Pending
indefinitely (the scheduler retries with back-off). The event message is a
per-reason tally across all nodes β it tells you exactly how many nodes each
predicate eliminated, which is the fastest path to the root cause.
- kubernetes (kube-scheduler)
high β the pod never runs. For a scaling event or new rollout this blocks capacity; for a single-replica workload it is a full outage of that service.
- Insufficient allocatable CPU or memory: the pod's
requestsexceed what any node has free. - Taints on nodes that the pod does not tolerate.
nodeSelector/nodeAffinity/nodeNamethat no node matches.- Pod / node anti-affinity or
topologySpreadConstraintsthat cannot be satisfied with current placement. - Unsatisfiable volume constraints (a PVC bound to a zone with no schedulable
node), or
podAntiAffinityrequiring more nodes than exist.
The scheduler runs each pending pod through two phases: filtering (predicates
like fit, taints, affinity, volume zone) to produce feasible nodes, then scoring
to pick the best. FailedScheduling means the filtering phase eliminated every
node. The message aggregates the reason each node was rejected. Because requests
(not limits) drive the fit check, a pod can be unschedulable even on a node that
looks idle if existing requests already reserve the capacity. Preemption only
helps if lower-priority victims exist; "No preemption victims found" means even
evicting pods would not free a fitting node.
# The FailedScheduling event with the per-reason node tally
kubectl describe pod <pod> -n <namespace>
# The pod's CPU/memory requests that must fit
kubectl get pod <pod> -n <namespace> \
-o jsonpath='{.spec.containers[*].resources.requests}'
# Allocatable vs allocated capacity per node
kubectl describe nodes | grep -A6 'Allocated resources'
# Node taints that may be blocking the pod
kubectl get nodes -o json \
| jq '.items[] | {name:.metadata.name, taints:.spec.taints}'Warning FailedScheduling default-scheduler 0/12 nodes are available:
3 Insufficient cpu, 4 Insufficient memory, 3 node(s) had untolerated taint ...
The dominant phrase identifies the fix: Insufficient cpu/memory β capacity or
oversized requests; untolerated taint β add a toleration; didn't match node affinity/selector β fix the selector or label a node; had volume node affinity conflict β PVC zone mismatch.
-
If capacity is the issue, lower the pod's
requeststo a realistic value or add nodes / scale the cluster autoscaler. -
To run on tainted nodes, add a matching toleration:
tolerations: - key: "dedicated" operator: "Equal" value: "gpu" effect: "NoSchedule"
-
Fix a
nodeSelector/nodeAffinitythat no node matches, or label a node so it matches. -
Relax
requiredDuringSchedulingspread/affinity topreferredif it is over-constrained.
kubectl get pod <pod> -n <namespace> -w
# Expect: STATUS moves Pending -> ContainerCreating -> Running with a node assigned.- Set
requestsfrom observed usage so the fit check reflects reality. - Keep the cluster autoscaler configured with headroom for burst scheduling.
- Review taints/affinity in CI against the actual node pool labels.
- Prefer
preferredDuringSchedulingfor spread to avoid hard unschedulability.
kubernetes Β· scheduler Β· pending Β· resources Β· production