PV reclaim slow or stuck — controller not picking up Released volumes
PV stays in Released state for hours after PVC deletion
Focused incident mode — strips away everything but this runbook.
Symptoms
- PV stays in Released state for hours after PVC deletion
- Underlying cloud volume (EBS, disk) still exists after PV release
- New PVC cannot bind because the old PV has not been reclaimed
PV reclaim is handled by the CSI controller. If it is down or rate-limited, Released volumes accumulate and cloud costs grow. Monitor Released PV count as an operational metric.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
PV status and policy
kubectl get pv -o jsonpath='{range .items[*]}{.metadata.name}: {.status.phase} policy={.spec.persistentVolumeReclaimPolicy}{"\n"}{end}'CSI controller pod health
kubectl get pods -n kube-system | grep -E 'csi|provisioner'
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
- No CSI controller pods in kube-system
- PV released but underlying disk still exists
Confirm before fixing
kubectl get pods -n kube-system | grep -E 'csi|ebs'Check CSI controller pods
Fix
kubectl rollout restart deployment/ebs-csi-controller -n kube-systemRestart the CSI controller
Expected: deployment.apps/ebs-csi-controller restarted
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 get pv -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,POLICY:.spec.persistentVolumeReclaimPolicyList PVs and their reclaim status
kubectl get pods -n kube-system | grep -E 'csi|provisioner'Check CSI controller health
kubectl rollout restart deployment/ebs-csi-controller -n kube-systemRestart the CSI controller if unhealthy
kubectl patch pv <pv> -p '{"spec":{"claimRef":null}}'Clear claimRef to force the PV to Available (if appropriate)
Prevention
- Monitor PV phase and alert on Released state > 5 minutes.
- Ensure CSI controller has PDBs and is monitored for crashes.
- Use Delete reclaim policy unless the volume holds data that must survive PVC deletion.
- Test PVC create/delete cycles in staging to validate the full lifecycle.
Related runbooks
Same stack, same failure family — worth a skim.
kubectl get pv shows status Released for extended period
kubectl get pvc shows Pending
StatefulSet pods stuck in Pending or ContainerCreating sequentially
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.