This scheduling error occurs when a PersistentVolume is bound to a specific zone or node, but the pod cannot be scheduled there due to conflicting constraints.
Fixes node(s) had volume node affinity conflict
kubectl describe pv <pv-name>kubectl describe pv <pv-name>node(s) had volume node affinity conflict
On this page
The "volume node affinity conflict" error indicates that Kubernetes cannot find a node where both the pod can run AND the PersistentVolume can be attached. This commonly occurs in multi-zone cloud environments where storage volumes are zone-bound. Cloud provider storage (AWS EBS, GCP Persistent Disks, Azure Managed Disks) can only attach to nodes in the same availability zone. When a PersistentVolume is created in Zone A but your pod needs to run in Zone B (due to other scheduling constraints), this conflict arises. The root cause is often the order of operations: the volume was provisioned before pod scheduling determined the best node placement.
View the PV to see which nodes it can attach to:
kubectl describe pv <pv-name>Look for:
Node Affinity:
Required Terms:
Term 0: topology.kubernetes.io/zone in [us-east-1a]View what's preventing the pod from scheduling to the volume's zone:
kubectl describe pod <pod-name>Look at Events and any nodeSelector, affinity, or anti-affinity rules in the spec.
Update your StorageClass to defer volume binding until pod scheduling:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard-wait
provisioner: kubernetes.io/aws-ebs # or your provider
volumeBindingMode: WaitForFirstConsumerThis ensures the volume is created in the same zone where the pod is scheduled.
If the PVC was created with Immediate binding, you need to recreate it:
# Backup any data first!
kubectl delete pvc <pvc-name>
# Recreate PVC using new StorageClass
kubectl apply -f pvc-with-new-storageclass.yamlWarning: This deletes the volume and data if using Delete reclaim policy.
Use allowedTopologies to control where volumes are created:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: zone-restricted
provisioner: kubernetes.io/aws-ebs
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/zone
values:
- us-east-1a
- us-east-1bFor StatefulSets, this error often occurs after node failures. The PVC remains bound to a zone-specific PV, but the replacement pod might try to schedule elsewhere.
Options for StatefulSets:
1. Use regional persistent disks (GKE) that can attach across zones
2. Manually delete the PVC to allow fresh provisioning (data loss)
3. Use storage replication solutions (Longhorn, Rook-Ceph)
If you're using local volumes, WaitForFirstConsumer is mandatory. Local volumes must have explicit nodeAffinity matching the node where storage exists:
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-with-local-storage