## TL;DR
The "0/3 nodes are available" prefix is just the headline; the reasons after it name exactly why each node was rejected (taints, insufficient CPU, affinity mismatch, volume conflicts). Read the whole message, count which reason dominates, and fix that constraint. Most cases resolve to resource requests too large, taints without tolerations, or affinity rules that match nothing.

## The query
```text
Kubernetes FailedScheduling "0/3 nodes are available": how to read the full message
```

## Use this when
- Pods sit in Pending with FailedScheduling events
- The message lists multiple rejection reasons
- You need to tell resource problems from constraint problems
- Teaching scheduler basics

## Not for when
- Pods that schedule successfully but then fail
- Node-level kubelet problems
- Descheduler evictions

## Steps

### Step 1: Get the complete event message
Describe the pod and read the full FailedScheduling event text, not just the first line. The message enumerates per-node rejection reasons; truncation in dashboards hides the useful part.
Expected output: the full list of reasons, e.g. "1 Insufficient cpu, 2 node(s) had taints".

### Step 2: Group the reasons by type
Tally the reasons: resource reasons (Insufficient cpu/memory), constraint reasons (taints, affinity, node selector), and volume reasons (node affinity conflict, volume already attached). The dominant group is your problem class.
Expected output: one dominant reason class identified.

### Step 3: For resource reasons, check requests vs capacity
Compare the pod's CPU/memory requests against node allocatable resources. Requests that exceed any single node's capacity can never schedule. Lower the requests or add bigger nodes.
Expected output: requests fitting within at least one node's allocatable capacity.

### Step 4: For constraint reasons, audit taints and affinity
List node taints and the pod's tolerations and affinity rules. A taint applied cluster-wide without a matching toleration blocks everything; an affinity rule referencing a label that exists nowhere matches nothing.
Expected output: the specific taint, label, or rule blocking scheduling, corrected.

### Step 5: Re-check after the fix and watch for partial scheduling
After fixing, the pod should schedule. If it schedules on some replicas but not all, you have a capacity edge: enough room for N pods but not N+1, which is a scaling signal, not a bug.
Expected output: pods scheduled; any remaining Pending pods explained by genuine capacity limits.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_luBiUBewrar1f7owJaiYPQ
