Unable to attach or mount volumes: timed out waiting for the condition
Fix "Unable to attach or mount volumes": check Multi-Attach on a ReadWriteOnce volume, a zone mismatch or a stale attachment. Covers CSI drivers and limits.
Unable to attach or mount volumes: unmounted volumes=[data], unattached volumes=[data kube-api-access-x7k2q]: timed out
Incident Overview
KubernetesKubernetes
Fix "Unable to attach or mount volumes": check Multi-Attach on a ReadWriteOnce volume, a zone mismatch or a stale attachment. Covers CSI drivers and limits.
hard fix·6 min read
By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026
Unable to attach or mount volumes: unmounted volumes=[data], unattached volumes=[data kube-api-access-x7k2q]: timed out waiting for the condition Multi-Attach error for volume "pvc-9f2a..." Volume is already used by pod(s) api-7d4f8c9b6-xk2mn AttachVolume.Attach failed for volume "pvc-9f2a..." : rpc error: code = Internal desc = Could not attach volume to node
Do this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• Read which volume is stuck and why
"Multi-Attach error" names the Pod currently holding the volume and is a different problem from a plain timeout. Note the exact wording before going further.
• Check whether the volume and the node are in the same zone
Compare against the node the Pod landed on. A zonal disk in eu-west-1a can never attach to a node in eu-west-1b, and the Pod will wait indefinitely rather than fail.
• Look for a leftover VolumeAttachment from a dead node
An attachment pointing at a node that no longer exists blocks every future attach of that volume. Deleting the stale VolumeAttachment releases it.
The kubelet asked the CSI driver to attach a volume and gave up waiting. The Pod sits in ContainerCreating indefinitely. There are four distinct causes and the event text tells you which.
kubectl describe pod my-pod | grep -A15 Events
Multi-Attach: the most common one
ReadWriteOnce means the volume can be mounted read-write by one node at a time. Not one Pod: one node. This trips people up during rolling updates.
A Deployment with strategy: RollingUpdate starts the new Pod before terminating the old one. If they land on different nodes, the new one cannot attach and waits for the old one to release, which only happens once the new one is Ready. Deadlock.
Find the holder:
For a single-replica workload with a ReadWriteOnce volume, use Recreate:
The old Pod terminates fully before the new one starts. You accept a few seconds of downtime, which for a workload that cannot run two copies anyway is not a real loss.
A StatefulSet avoids this by design: each replica gets its own PVC from volumeClaimTemplates, and the controller never runs two Pods with the same ordinal.
If you genuinely need several Pods writing the same volume, you need ReadWriteMany, which means a file-based backend such as EFS, Azure Files or an NFS server. EBS and GCE persistent disks are block devices and cannot do it.
Multi-Attach error for volume "pvc-9f2a..." Volume is already used by pod(s) api-7d4f8c9b6-xk2mn
Zone mismatch
A zonal disk exists in one availability zone. A node in another zone cannot attach it, ever.
Disk in eu-west-1a, node in eu-west-1b, and the Pod waits forever.
The prevention is volumeBindingMode: WaitForFirstConsumer on the StorageClass:
With Immediate, the volume is created as soon as the PVC exists, in whichever zone the provisioner picks, and the scheduler must then find a node there. With WaitForFirstConsumer, the scheduler places the Pod first and the volume is created in that Pod's zone. It is the correct setting for zonal storage in a multi-zone cluster, and the default on most managed clusters now.
Changing it does not move existing volumes. A PVC already bound to a disk in the wrong zone has to be recreated, which means restoring from a snapshot if the data matters.
kubectl get pv pvc-9f2a... -o jsonpath='{.spec.nodeAffinity}' | jq
kubectl get node ip-10-0-2-15 -o jsonpath='{.metadata.labels.topology\.kubernetes\.io/zone}'Stale attachment after a node failure
When a node dies hard, the controller may never get to detach the volume, leaving a VolumeAttachment pointing at a node that no longer exists.
If ip-10-0-1-99 is gone from kubectl get nodes, that attachment is stale and blocks every future attach:
Check the cloud console too. AWS occasionally leaves an EBS volume in attaching or attached to a terminated instance, and only a detach there clears it:
--force can corrupt a filesystem that is still being written to. Only use it once you are certain the instance is gone.
kubectl get volumeattachment \ -o custom-columns=NAME:.metadata.name,PV:.spec.source.persistentVolumeName,NODE:.spec.nodeName,ATTACHED:.status.attached
The CSI driver itself
If several volumes are stuck at once, suspect the driver rather than any one volume:
The node plugin is a DaemonSet, so a node missing its CSI node Pod cannot mount anything. That shows up as a single node where everything with a volume fails.
IAM is the other frequent cause on EKS. The controller needs ec2:AttachVolume, ec2:DetachVolume, ec2:CreateVolume and ec2:DescribeVolumes; a missing permission surfaces as an rpc error in the Pod events with the real reason in the controller log.
kubectl -n kube-system get pods -l app=ebs-csi-controller kubectl -n kube-system logs -l app=ebs-csi-controller -c ebs-plugin --tail=50 kubectl -n kube-system get pods -l app=ebs-csi-node -o wide
Instance attachment limits
Every instance type has a maximum number of attached volumes, and Nitro instances count ENIs and the root volume towards it. Once a node is at its limit, further attaches fail even though the disk and zone are fine.
The scheduler is aware of this via the CSI driver's reported limit, so it usually avoids overfilling a node. It gets it wrong when volumes are attached outside Kubernetes.
kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=ip-10-0-1-42 | wc -l
A checklist
Frequently Asked Questions
What does "Multi-Attach error for volume" mean?
A ReadWriteOnce volume can be mounted read-write by only one node at a time, and a second node is trying to attach it. The usual trigger is a rolling update where the new Pod is scheduled to a different node than the old one: the new Pod cannot attach until the old one releases, and the old one is not terminated until the new one is Ready, so the two deadlock. For a single-replica workload the fix is strategy: Recreate, which terminates the old Pod first.
How do I fix a zone mismatch between a PersistentVolume and a node?
You cannot move a zonal disk, so the existing PVC must be recreated in the right zone, restoring from a snapshot if the data matters. To stop it recurring, set volumeBindingMode: WaitForFirstConsumer on the StorageClass. That defers volume creation until the scheduler has chosen a node, so the disk is created in the zone where the Pod actually is. With the older Immediate mode the disk is created first, in whichever zone the provisioner picks, and the scheduler is then constrained to that zone.
Why is my volume still attached to a node that no longer exists?
When a node terminates abruptly the controller may never complete the detach, leaving a VolumeAttachment object referencing the dead node. That object blocks any future attach of the volume. List them with kubectl get volumeattachment and delete the stale one. Check the cloud provider too: AWS sometimes leaves an EBS volume attached to a terminated instance, which needs aws ec2 detach-volume, and the --force flag there can corrupt a filesystem if the instance is somehow still writing.
Can several Pods share one PersistentVolumeClaim?
Only if the access mode is ReadWriteMany, and only with a storage backend that supports it. Block storage such as EBS, GCE persistent disks and Azure managed disks cannot, because a block device mounted read-write by two hosts corrupts the filesystem. File-based backends can: EFS, Azure Files, and NFS. Note that ReadWriteOnce permits multiple Pods on the same node to share the volume, which is why it sometimes appears to work until the scheduler places a replica elsewhere.
Why does a Pod hang in ContainerCreating with no error at all?
Check whether the PVC is simply waiting: with volumeBindingMode: WaitForFirstConsumer, a PVC stays Pending with a waiting for first consumer message until a Pod that uses it is scheduled, which is normal rather than a fault. If the PVC is Bound and the Pod still hangs, look at the CSI node plugin on that specific node, since the mount happens there. A node missing its CSI DaemonSet Pod fails every volume mount while the rest of the cluster works fine.
Reference and practice
Learn the underlying concept
Other Kubernetes errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.