← Debugging Guides

阅读中文版本

Kubernetes PVC Pending — No StorageClass or Binding Failure

Fix a PVC stuck Pending by matching a StorageClass, checking access modes and capacity, and inspecting the provisioner events.

intermediatedebuggingkubernetesstoragepvc

Symptoms

  • A PersistentVolumeClaim stays Pending indefinitely
  • Pods using the PVC stay Pending waiting for the volume
  • Events show "no persistent volumes available for this claim"

Possible causes

  • No default StorageClass exists and the PVC does not name one
  • The requested access mode or capacity is unsupported by the class
  • The provisioner is missing or lacks permission to create volumes

Diagnosis steps

Inspect PVC status and events

kubectl describe pvc <pvc> | tail -20

Interpretation

The events name the failure: missing class, unsupported mode, or provisioner error.

List available storage classes

kubectl get storageclass

Interpretation

The (default) marker shows which class binds unqualified PVCs; absence means you must name one.

Root cause

Dynamic provisioning requires a StorageClass, either named on the PVC or set as cluster default. Without one, or when the requested access mode or capacity is unsupported, no provisioner creates a volume and the PVC stays Pending.

Fix

Name an existing StorageClass on the PVC, mark a valid default class, request a supported access mode and capacity, and ensure the provisioner has the needed permissions.

Risk note

Changing access mode after creation is not allowed; deleting the PVC may lose data unless the reclaim policy is Retain.

Verify the fix

Confirm the PVC binds and reports Bound; verify the consuming pod starts and mounts the volume.

Symptoms

This guide profiles the failure behind “Kubernetes PVC Pending — No StorageClass or Binding Failure”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • A PersistentVolumeClaim stays Pending indefinitely
  • Pods using the PVC stay Pending waiting for the volume
  • Events show “no persistent volumes available for this claim”

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Inspect PVC status and events

kubectl describe pvc <pvc> | tail -20

The events name the failure: missing class, unsupported mode, or provisioner error.

Step 2: List available storage classes

kubectl get storageclass

The (default) marker shows which class binds unqualified PVCs; absence means you must name one.

Likely contributors, in order of frequency:

  • No default StorageClass exists and the PVC does not name one
  • The requested access mode or capacity is unsupported by the class
  • The provisioner is missing or lacks permission to create volumes

Root Cause

Dynamic provisioning requires a StorageClass, either named on the PVC or set as cluster default. Without one, or when the requested access mode or capacity is unsupported, no provisioner creates a volume and the PVC stays Pending.

The Fix

Name an existing StorageClass on the PVC, mark a valid default class, request a supported access mode and capacity, and ensure the provisioner has the needed permissions.

Watch out: Changing access mode after creation is not allowed; deleting the PVC may lose data unless the reclaim policy is Retain.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data
spec:
  storageClassName: standard   # name a class that exists
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 10Gi

# set a default class if none exists
# kubectl patch storageclass standard -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

Verify and Prevent

Confirm the PVC binds and reports Bound; verify the consuming pod starts and mounts the volume.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.