Kubernetes
PVC
WaitForFirstConsumer
Pod
FailedScheduling

Kubernetes pvc is in WaitForFirstConsumer and pod is in FailedScheduling

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

WaitForFirstConsumer on a PersistentVolumeClaim is often normal, not a failure. The real issue begins when the Pod is also stuck in FailedScheduling, because Kubernetes is then unable to find a node placement that satisfies both the Pod constraints and the storage topology requirements.

What WaitForFirstConsumer Means

Some StorageClasses use:

volumeBindingMode: WaitForFirstConsumer

That tells Kubernetes to delay binding or dynamic provisioning until a Pod that uses the PVC is being scheduled. The purpose is to avoid provisioning a volume in the wrong zone or on the wrong topology segment too early.

So the PVC status by itself often means:

  • storage is waiting for scheduling context
  • the scheduler has not yet produced a valid placement decision

That is expected behavior for topology-aware storage.

Why the Pod Gets FailedScheduling

With delayed volume binding, the scheduler has to solve a combined problem:

  • can the Pod run on this node
  • can the volume be provisioned or bound for this node

If the answer is no for every candidate node, the Pod stays unscheduled and the PVC remains in WaitForFirstConsumer.

Typical reasons include:

  • node selectors or affinity that conflict with available storage topology
  • taints that the Pod does not tolerate
  • insufficient CPU or memory on the nodes that match the storage constraints
  • a CSI driver or storage class that cannot provision in the zone the Pod requires

This is why the two statuses often appear together. They are symptoms of the same placement deadlock.

Check the Pod Events First

The best first step is not staring at the PVC phase. It is reading the scheduler events for the Pod.

bash
kubectl describe pod <pod-name>
kubectl describe pvc <pvc-name>
kubectl get storageclass <storage-class> -o yaml

The Pod events often tell you exactly what the scheduler could not satisfy, such as:

  • no nodes match node affinity
  • node has untolerated taint
  • insufficient resources
  • volume node affinity conflict

Those messages are more actionable than the raw phase names alone.

A Typical Topology Mismatch

Here is a common pattern: the Pod is pinned to one zone, but the storage class can only provision in another or there are no eligible nodes left in the requested zone.

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: app
5spec:
6  nodeSelector:
7    topology.kubernetes.io/zone: us-east-1a
8  containers:
9    - name: app
10      image: nginx
11      volumeMounts:
12        - name: data
13          mountPath: /data
14  volumes:
15    - name: data
16      persistentVolumeClaim:
17        claimName: app-data

If no schedulable node in us-east-1a can satisfy the volume requirements, the Pod fails scheduling and the PVC never leaves its waiting state.

Do Not Bypass the Scheduler with nodeName

One subtle issue is manually setting spec.nodeName on the Pod. That bypasses normal scheduling logic, which means the delayed-binding workflow may not proceed the way you expect.

When using WaitForFirstConsumer, let the scheduler do the placement work unless you have a very specific reason and fully understand the consequences. Otherwise you can create a situation where the PVC stays pending because the normal scheduling-driven binding flow never completes properly.

How to Fix It

The solution depends on which side is too restrictive.

Possible fixes on the Pod side:

  • remove unnecessary nodeSelector rules
  • relax node affinity or anti-affinity
  • add required tolerations
  • request fewer resources if the nodes are too full

Possible fixes on the storage side:

  • use a StorageClass that supports the needed topology
  • provision nodes in the matching zone
  • verify CSI driver topology support and capacity

The main goal is to give Kubernetes at least one node where both compute placement and storage placement are valid.

Common Pitfalls

The most common mistake is treating WaitForFirstConsumer as the root cause. Often it is just the storage class behaving correctly while the real problem is elsewhere in scheduling.

Another issue is inspecting only the PVC and ignoring the Pod events. The scheduler usually explains the actual reason in the Pod description.

People also focus only on CPU and memory while missing zone, affinity, taint, or topology constraints. Those are frequently the real blockers.

Finally, manually pinning Pods with nodeName can interfere with the normal delayed-binding workflow and make diagnosis harder.

Summary

  • 'WaitForFirstConsumer usually means the PVC is waiting for scheduling context before binding.'
  • If the Pod is also in FailedScheduling, Kubernetes cannot satisfy compute and storage placement at the same time.
  • Inspect Pod events, PVC details, and the StorageClass together.
  • Look for topology mismatches, affinity rules, taints, and resource shortages.
  • Fix the scheduling constraint, and the PVC will often bind as a consequence.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.