PersistentVolumeClaim stuck in Pending — no provisioner
kubectl get pvc shows Pending
Focused incident mode — strips away everything but this runbook.
Symptoms
- kubectl get pvc shows Pending
- Pod that mounts the volume stays Pending
- No StorageClass 'provisioner' events after wait
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
PVC status + storage class
kubectl describe pvc <pvc> -n <namespace>Available storage classes
kubectl get storageclass
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- PVC has no storageClassName and no default class is annotated
- kubectl get storageclass returns a class without the default annotation
Confirm before fixing
kubectl get storageclass -o custom-columns=NAME:.metadata.name,PROVISIONER:.provisioner,DEFAULT:.metadata.annotations.storageclass\.kubernetes\.io/is-default-classInspect classes and default annotation
Fix
kubectl patch storageclass <class> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'Mark a real class as default (or add storageClassName to the PVC)
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
kubectl describe pvc <pvc> -n <namespace> | tail -20Read the exact reason
kubectl get storageclass -o wideCheck provisioner availability
kubectl patch storageclass <class> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'Fix default class if missing
kubectl get pvc <pvc> -n <namespace>Confirm it flips to Bound
Prevention
- Install the platform CSI driver as part of cluster bootstrap.
- Always declare storageClassName explicitly on PVCs.
- Monitor pvc status and alert on Pending for > 5 minutes.
Related runbooks
Same stack, same failure family — worth a skim.
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.