FailedAttachVolume: The volume could not be attached to the node the pod was scheduled to
FailedAttachVolume means the control plane asked the storage system to attach a disk to a node and the attach did not succeed. It happens before mounting, so no filesystem work has been attempted yet.
Applies to: All Kubernetes versions using attachable volume types
What it means
Block volumes go through two stages: attach, which makes the device visible to the node, and mount, which makes a filesystem on it visible to the container. FailedAttachVolume is a failure of the first stage, handled by the attach-detach controller rather than the kubelet. The distinction matters because the causes are infrastructure-level rather than pod-level: cloud provider attachment limits, a volume still held by another node, a zone mismatch between the volume and the node, or credentials the CSI driver uses to talk to the storage API. Nothing in the pod spec will fix most of these.
Most common causes
- The volume is still attached to another node, usually because a pod on that node has not fully terminated.
- The node has reached its cloud provider limit on attached disks. Every provider has one, and it is lower than people expect.
- The volume is in a different availability zone from the node, which most block storage cannot cross.
- The CSI driver's credentials lack permission to attach, or its controller pod is not running.
- The storage backend is rate limiting or is temporarily unavailable.
- The volume was deleted out of band, so the object exists in Kubernetes but the disk does not.
How to diagnose it
- Read the event message:
kubectl describe pod POD. Cloud provider errors are passed through and are usually explicit. - Check where the volume currently is:
kubectl get volumeattachmentand look for an attachment to a different node. - Check the CSI controller's logs:
kubectl logs -n kube-system -l app=CSI_DRIVER --all-containers. - Compare zones:
kubectl get node NODE -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'against the volume's zone. - Count attached volumes on the node against the provider's documented limit.
- Confirm the disk still exists in the storage backend's own console or API.
How to fix it
- Ensure the pod holding the volume on the other node has fully terminated. A pod stuck in
Terminatingis the most common cause of this and must be resolved first. - Spread workloads so no single node exceeds its attachment limit, or use larger nodes with higher limits.
- Use a topology-aware StorageClass with
volumeBindingMode: WaitForFirstConsumerso volumes are provisioned in the zone where the pod will actually run. - Fix the CSI driver's permissions, or restart its controller if it is unhealthy.
- If the underlying disk was deleted, delete the PersistentVolume object too — Kubernetes cannot attach something that no longer exists.
Notes
volumeBindingMode: WaitForFirstConsumer prevents a whole class of zone conflicts by deferring provisioning until the scheduler has picked a node. Setting it on the StorageClass is worth doing before these failures start rather than after.
Related
- Multi-Attach error — The volume is already attached to another node
- FailedMount — A volume could not be mounted into the pod
Sources
- Kubernetes documentation — Persistent Volumes
- Kubernetes documentation — Storage Classes: volume binding mode
- Container Storage Interface specification