Home / Tutorials / Kubernetes

Kubernetes · Scaling · Production down

Fix: pod has unbound immediate PersistentVolumeClaims

Error 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims

By the Erzon engineering team · A step-by-step fix, not a forum thread

The scheduler error 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims means the pod cannot be placed anywhere because a PersistentVolumeClaim it depends on has not bound to a volume. The 0/3 is your node count, and the reason is storage, not CPU or memory. The pod stays Pending until the PVC binds, so the real work is figuring out why the claim is stuck.

0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. preemption: 0/3 nodes are available

What this error means

A pod that mounts a PersistentVolumeClaim can only be scheduled once that claim is bound to a PersistentVolume. With a StorageClass in Immediate binding mode, the volume is expected to exist before scheduling, so if the PVC is still Pending the scheduler has nothing to attach and refuses every node. The PVC stays Pending when there is no StorageClass to satisfy it, when no default StorageClass is set and the claim named none, when the dynamic provisioner (the CSI driver) is down or erroring, or when a volume was provisioned in a zone that no eligible node can reach. The pod message is only the visible symptom. The cause is always on the PVC, and kubectl describe pvc states it plainly.

Common causes

  • No StorageClass matches the claim, or the named StorageClass does not exist.
  • No default StorageClass is set and the PVC did not name one, so nothing provisions it.
  • The dynamic provisioner or CSI driver is not running, crashing, or lacks cloud permissions to create the volume.
  • Immediate binding created (or tried to create) the volume in a zone where the pod cannot be scheduled, a topology mismatch.
  • A storage quota or cloud API limit blocks new volume creation.
  • A statically provisioned PV that does not match the claim’s size, access mode, or selector, so binding never happens.

How to fix it

Stabilize

  1. If a deploy introduced this and the workload was previously running, roll back to the last working revision so service continues while you fix storage:
kubectl rollout undo deployment/<name>

Diagnose

  1. Read the PVC status and its events. This is where the actual reason lives, whether it is a missing class or a provisioner error:
kubectl describe pvc <pvc-name> -n <namespace>
  1. Check what StorageClasses exist and which, if any, is the default (marked (default)):
kubectl get storageclass
  1. Look at the claim itself to see which StorageClass and access mode it asks for:
kubectl get pvc <pvc-name> -n <namespace> -o yaml
  1. Confirm the CSI driver or provisioner pods are healthy, since a down provisioner leaves every new PVC Pending:
kubectl get pods -n kube-system | grep -iE 'csi|provisioner'

Fix

  1. If no default StorageClass exists, mark the correct one default so unqualified claims provision:
kubectl patch storageclass <name> -p \
  '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
  1. If the claim names a StorageClass that does not exist, correct the storageClassName in the PVC (or the volumeClaimTemplate) to a real one and reapply. A PVC’s storage request is immutable, so you may need to recreate it:
kubectl delete pvc <pvc-name> -n <namespace>
kubectl apply -f pvc.yaml
  1. If the CSI driver is down or erroring, restart it and read its logs for the real failure (often missing cloud IAM permissions):
kubectl rollout restart daemonset/<csi-driver> -n kube-system
kubectl logs -n kube-system -l app=<csi-driver> --tail=50
  1. If the problem is topology (a volume in the wrong zone), switch the StorageClass to WaitForFirstConsumer so the volume is provisioned after a node is chosen, matching zones:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer

How to prevent it

  • Set exactly one default StorageClass in every cluster so unqualified PVCs always have somewhere to provision.
  • Use volumeBindingMode: WaitForFirstConsumer for zonal cloud storage so volumes are created in a zone where the pod can actually run.
  • Monitor CSI driver and provisioner pods and alert when they are not healthy, since their failure blocks all new storage.
  • Validate that every StorageClass a manifest references exists before you deploy, in CI.
  • Track storage quotas and cloud volume limits so provisioning does not silently fail at scale.

When to call a senior engineer

Call for help when the StorageClass and provisioner all look correct but PVCs still will not bind, when zone and topology constraints make volumes land where pods cannot reach them, or when a stateful workload is down in production and the storage path is unclear under pressure. Erzon engineers can trace the claim back to the provisioner, driver, and topology that stalled it, bind the volume, and set the StorageClass and CSI setup so stateful pods schedule reliably.

Related errors we fix

Still down after this?

Want a senior engineer to just fix it?

Paste this exact error into the form. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.

Book a fix

← Back to all error fixes

Still down?

Get a senior engineer on it now

Leave your email and a line about what is happening. A senior engineer replies within one business hour with what is likely wrong and a flat quote. Triage is free.

Or email [email protected]. Same engineers, same one-hour clock.