Skip to content

Revision 1 — the current text. The evidence on this page is this revision’s own — it has not been carried forward from, or to, any other revision.

Diagnosing FailedScheduling / Insufficient cpu

Separates a transient shortfall from nodes still rejoining after an upgrade, genuine cluster-wide CPU contention needing more capacity, and a pod whose CPU request is simply too large to fit on any node in the pool at all. It does not cover FailedScheduling caused by node affinity, taints/tolerations, or Insufficient memory/pods — the same describe-pod approach applies, but the resource name in the message and the fix differ.

Unverifiedno reproductions yetWhy this confidence?
Revision 1published by DevYou curation

Symptoms

The diagnostic path

8 steps, exactly as this revision published them.

  1. Step 1 · StartPods Pending with FailedScheduling / Insufficient cpu

    This is a capacity-fit problem: the sum of already-scheduled CPU requests plus this pod's request exceeds what any single node currently has free. It's common right after a cluster or node-pool upgrade because upgrades typically cordon and replace nodes in batches, temporarily shrinking available capacity.

    What happens next

    • passed step 2, Confirm the message actually names Insufficient cpu
  2. Step 2 · TestConfirm the message actually names Insufficient cpu

    Read the FailedScheduling event text precisely — the same mechanism applies to memory, taints, or affinity, but the fix is different for each.

    Read-onlysh
    kubectl describe pod <pod-name> -n <namespace>

    Expected result

    Warning  FailedScheduling  12s (x8 over 4m)  default-scheduler  0/6 nodes are available: 6 Insufficient cpu.

    What happens next

    • passed step 3, Check whether nodes are still catching up from the upgrade
    • failed step 4, This is a different scheduling failure
    • unknown step 4, This is a different scheduling failure
  3. Step 3 · TestCheck whether nodes are still catching up from the upgrade

    Look for NotReady nodes, nodes marked SchedulingDisabled (cordoned), or nodes that were only just created and haven't finished joining.

    Read-onlysh
    kubectl get nodes -o wide

    Expected result

    NAME       STATUS                     ROLES    AGE   VERSION
    node-3     Ready,SchedulingDisabled   <none>   400d  v1.33.0
    node-4     Ready                      <none>   2m    v1.33.0

    What happens next

    • passed step 5, Root cause: capacity is temporarily down while nodes rejoin
    • failed step 6, Compare the pod's CPU request against the largest node's allocatable CPU
    • unknown step 6, Compare the pod's CPU request against the largest node's allocatable CPU
  4. Step 4 · EndThis is a different scheduling failure

    If the message names a different resource (Insufficient memory, Insufficient pods) or mentions node affinity/taints instead, the diagnosis approach here still applies (check what the scheduler is actually comparing) but the specific fix does not — resize or reconfigure the resource actually named in the message.

  5. Step 5 · Root causeRoot cause: capacity is temporarily down while nodes rejoin

    Some nodes are cordoned or NotReady, or were only just created — this is the node rollout that usually accompanies a cluster or node-pool version upgrade. Capacity should recover once the rollout finishes; if using a managed node pool or cluster autoscaler, confirm it isn't itself stuck (quota limits, a node template that fails to boot) before assuming it will resolve on its own.

  6. Step 6 · TestCompare the pod's CPU request against the largest node's allocatable CPU

    All nodes are Ready and none are cordoned — the question now is whether the pod could fit anywhere at all, or whether it's simply contention for space that does exist.

    Read-onlysh
    kubectl describe node <node-name> | grep -A5 Allocatable; kubectl get pod <pod-name> -n <namespace> -o jsonpath='{.spec.containers[*].resources.requests.cpu}'

    Expected result

    Allocatable:
      cpu:                3800m
      memory:             14Gi
    2000m

    What happens next

    • passed step 7, Root cause: legitimate contention — the cluster needs more schedulable CPU
    • failed step 8, Fix: the pod's CPU request doesn't fit on any node in the pool
    • unknown step 8, Fix: the pod's CPU request doesn't fit on any node in the pool
  7. Step 7 · Root causeRoot cause: legitimate contention — the cluster needs more schedulable CPU

    The pod's request does fit under some node's allocatable CPU, so this is contention rather than an impossible fit: the cluster is at capacity for schedulable CPU right now. Check that the cluster autoscaler (or manual node pool scaling) is enabled, has headroom against any cloud-provider quota, and is actually configured to add the node type this workload needs.

  8. Step 8 · FixFix: the pod's CPU request doesn't fit on any node in the pool

    If the pod's CPU request exceeds the allocatable CPU of every node type available, no amount of autoscaling fixes it — the scheduler will never find room. Reduce the request to something a real node can satisfy, or move the workload to a larger node pool/instance type.

    Changes statesh

    Changes system or service state. Review before running.

    Patches the deployment's pod template with the new CPU request, which triggers a rolling restart of the deployment's pods.

    kubectl set resources deployment/<deployment-name> -c=<container-name> --requests=cpu=500m -n <namespace>

Sources

Why this confidence?

What would strengthen it: 6 more independent reproductions. Reproductions from 3 more distinct environments.

This counts only what was recorded against revision 1 itself. Nothing reported against another revision is included here — see the revision history for why.