How to fix PersistentVolumeClaim is not bound in Kubernetes
This error occurs when a PersistentVolumeClaim (PVC) cannot find a matching PersistentVolume (PV) to bind to. Common causes include mismatched access modes, storage class issues, or no available volumes. The fix involves ensuring your PVC and PV specifications align correctly.
Quick fix
Fixes PersistentVolumeClaim is not bound
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>- Check PVC and PV status
- Verify access modes match
- Check storage class configuration
- Verify capacity requirements
kubectl get pvc -n <namespace>kubectl describe pvc <pvc-name> -n <namespace>PersistentVolumeClaim is not bound
What this error means
When Kubernetes reports "PersistentVolumeClaim is not bound," it means your PVC is stuck in a Pending state because it cannot find a suitable PersistentVolume to claim. This is a blocking issue—any pods depending on this PVC will not start until the binding succeeds. The PVC-to-PV binding process requires several criteria to match: storage capacity, access modes (ReadWriteOnce, ReadWriteMany, ReadOnlyMany), storage class, and optionally label selectors. If any of these don't align, Kubernetes cannot complete the binding. In clusters with dynamic provisioning enabled, a StorageClass provisioner automatically creates PVs when PVCs are submitted. If dynamic provisioning fails or isn't configured, you'll need to manually create matching PVs or troubleshoot the provisioner.
Typical symptoms
- Pod stuck in Pending state with "Pod has unbound immediate persistent volume claims" event
- kubectl get pvc shows PVC status as Pending indefinitely
- kubectl describe pvc shows "no persistent volumes available" in Events
- Application containers fail to start due to volume mounting failure
- CI/CD pipelines fail at the pod deployment stage
- Deployment rollout hangs waiting for pods to become ready
- StatefulSet pods remain in Pending state
Common causes
- AccessModes mismatch between PVC and available PVs (e.g., ReadWriteOnce vs ReadWriteMany)
- No PersistentVolume exists that meets the PVC capacity, storage class, or selector requirements
- StorageClass mismatch—PVC specifies a storageClassName that no PV or provisioner provides
- PVC requests more storage capacity than any available PV offers
- Available PV is already bound to another PVC (one-to-one binding)
- PV is in Released state with Retain reclaim policy, blocking new bindings
- StorageClass uses WaitForFirstConsumer binding mode but no pod has been scheduled yet
- Dynamic provisioner pod is not running, misconfigured, or lacks permissions
How to fix "PersistentVolumeClaim is not bound"
First, inspect your PVC status and events to understand why binding failed:
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name> -n <namespace>Look at the Events section for messages like "no persistent volumes available" or specific mismatch details. Also list available PVs:
kubectl get pv
kubectl describe pv <pv-name>Ensure your PVC and PV use compatible access modes. They must match exactly:
# PV access modes
spec:
accessModes:
- ReadWriteOnce # Must match PVC
# PVC access modes
spec:
accessModes:
- ReadWriteOnce # Must match PVCommon modes: ReadWriteOnce (single node), ReadWriteMany (multiple nodes), ReadOnlyMany (read-only multi-node).
Verify both PVC and PV reference the same storage class:
kubectl get storageclass
kubectl describe storageclass <name>For static provisioning, ensure PV has matching storageClassName:
# PV
spec:
storageClassName: manual
# PVC
spec:
storageClassName: manualFor dynamic provisioning, verify the provisioner pod is running:
kubectl get pods -n kube-system | grep -E 'provisioner|csi'PV capacity must be greater than or equal to PVC request:
# PV must have enough capacity
spec:
capacity:
storage: 10Gi
# PVC request must be <= PV capacity
spec:
resources:
requests:
storage: 5Gi # OK: 5Gi <= 10GiIf no PV has sufficient capacity, create a larger one or reduce your PVC request.
If a PV shows status "Released," it cannot be reused until reset. For Retain reclaim policy:
# Check PV status
kubectl get pv
# If Released, you have two options:
# Option 1: Delete and recreate the PV
kubectl delete pv <pv-name>
# Then recreate with same spec
# Option 2: Remove claimRef to make it Available again
kubectl patch pv <pv-name> -p '{"spec":{"claimRef": null}}'Warning: Option 2 may leave orphaned data on the volume.
If using WaitForFirstConsumer binding mode, the PVC stays Pending until a pod using it is scheduled:
kubectl get storageclass <name> -o yaml | grep volumeBindingModeThis is expected behavior for topology-aware storage. Create a pod that uses the PVC to trigger binding:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: your-pvc-nameIf no suitable PV exists, create one that matches your PVC:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: manual
persistentVolumeReclaimPolicy: Retain
hostPath: # For local testing only
path: /mnt/dataApply and verify binding:
kubectl apply -f pv.yaml
kubectl get pvc # Should now show BoundAdvanced notes
Cloud Provider Considerations:
- AWS EKS: Ensure the EBS CSI driver is installed and has proper IAM permissions. Check kubectl get pods -n kube-system -l app=ebs-csi-controller.
- GKE: Verify the Compute Engine persistent disk CSI driver is enabled. Regional PVs must match pod scheduling zones.
- AKS: Check Azure Disk or Azure File CSI driver status. Verify storage account quotas and regional availability.
Local Development:
- Minikube: Use minikube addons enable storage-provisioner for automatic provisioning.
- Kind: Requires manual StorageClass setup or the local-path-provisioner.
- Docker Desktop: Limited to hostPath volumes for local development.
Topology and Affinity:
When using WaitForFirstConsumer, the volume is provisioned in the same zone as the first pod. This prevents cross-zone mounting issues but means PVC binding depends on pod scheduling. Use kubectl describe pvc to see waiting status.
Pre-binding PVs:
For explicit PV-to-PVC mapping, use spec.volumeName in PVC and spec.claimRef in PV. The claimRef must include namespace:
spec:
claimRef:
namespace: my-namespace
name: my-pvcFrequently asked questions
- What does "PersistentVolumeClaim is not bound" mean?
- When Kubernetes reports "PersistentVolumeClaim is not bound," it means your PVC is stuck in a Pending state because it cannot find a suitable PersistentVolume to claim. This is a blocking issue—any pods depending on this PVC will not start until the binding succeeds. The PVC-to-PV binding process requires several criteria to match: storage capacity, access modes (ReadWriteOnce, ReadWriteMany, ReadOnlyMany), storage class, and optionally label selectors.
- How do I fix "PersistentVolumeClaim is not bound"?
- This error occurs when a PersistentVolumeClaim (PVC) cannot find a matching PersistentVolume (PV) to bind to. Common causes include mismatched access modes, storage class issues, or no available volumes. The fix involves ensuring your PVC and PV specifications align correctly.
- What causes "PersistentVolumeClaim is not bound"?
- AccessModes mismatch between PVC and available PVs (e.g., ReadWriteOnce vs ReadWriteMany) No PersistentVolume exists that meets the PVC capacity, storage class, or selector requirements StorageClass mismatch—PVC specifies a storageClassName that no PV or provisioner provides
- Is the "PersistentVolumeClaim is not bound" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- 📚Kubernetes Official Documentation
- 📖Kubernetes Docs: persistent volumes(Official Docs)
- 📖Kubernetes Docs: configure persistent volume storage(Official Docs)
- 💬
- 📝