pod has unbound immediate PersistentVolumeClaims — how to fix
Warning FailedScheduling default-scheduler 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available: 3 Preemption is not helpful for scheduling.
Quick fix: Run kubectl get pvc and kubectl describe pvc <name> to see why it's Pending. Check kubectl get storageclass for a (default) class; set storageClassName on the PVC or mark one default with kubectl patch storageclass <sc> -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'. With static PVs, make sure size, accessModes and storageClassName match.
What it means
A PVC with volumeBindingMode: Immediate (the default for many StorageClasses, and for PVCs without one) must be bound to a PersistentVolume before any pod using it can be scheduled. The pod stays Pending with this message until the claim binds. The fix is never on the pod — find out why the PVC is stuck.
kubectl get pvc -n myns
kubectl describe pvc data-myapp-0 -n myns # read the Events at the bottom
Cause 1: no default StorageClass
If the PVC has no storageClassName and the cluster has no default class, nothing provisions a volume. Events show no persistent volumes available for this claim and no storage class is set.
kubectl get storageclass
A default one is marked (default). Either set it on the PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
storageClassName: standard # a name from kubectl get storageclass
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
or make an existing class the default:
kubectl patch storageclass standard \
-p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Note: storageClassName can't be changed on an existing PVC — delete and recreate it (for StatefulSets, delete the PVC so it's recreated from volumeClaimTemplates).
Cause 2: no provisioner on a bare-metal / local cluster
kubeadm and bare-metal clusters ship no dynamic provisioner. Install one, for example the Rancher local-path provisioner (k3s includes it as local-path), an NFS provisioner, or your storage vendor's CSI driver. Minikube and kind include a default standard class; on minikube make sure the addons are on:
minikube addons enable storage-provisioner
minikube addons enable default-storageclass
Cause 3: the provisioner is failing
If a StorageClass exists, kubectl describe pvc shows provisioner events such as waiting for a volume to be created, either by external provisioner "ebs.csi.aws.com" or ProvisioningFailed. Check the CSI driver pods:
kubectl get pods -n kube-system | grep -i csi
kubectl logs -n kube-system <csi-controller-pod> -c csi-provisioner
On EKS, the EBS CSI driver add-on must be installed (it's required since Kubernetes 1.23) and its IAM role must have EBS permissions. Quota or zone problems also appear here.
Cause 4: static PV doesn't match the claim
With manually created PVs, a PVC binds only to a PV that satisfies all of:
- capacity ≥ requested storage
- the same
accessModes(e.g.ReadWriteOnce) - the same
storageClassName(both empty""counts as a match) volumeModeand anyselectorlabels
kubectl get pv
A PV in Released status was bound to a deleted claim and won't rebind automatically. Remove its claimRef to make it Available again (only if you're sure the data can be reused):
kubectl patch pv my-pv --type json -p '[{"op":"remove","path":"/spec/claimRef"}]'
Cause 5: PVC in the wrong namespace or misnamed
PVCs are namespaced. A pod in prod can't use a claim in default. Check that claimName in the pod matches exactly:
kubectl get pod mypod -o jsonpath='{.spec.volumes[*].persistentVolumeClaim.claimName}'
Tip: WaitForFirstConsumer
For zonal storage, use a StorageClass with volumeBindingMode: WaitForFirstConsumer so the volume is created in the zone where the pod is scheduled. With it, the PVC stays Pending until a pod uses it — that's normal.
Last updated 2026-10-30.