Skip to main content

Troubleshoot Pending pods and PVCs

A pod stays Pending while the scheduler cannot place it on any node. A PVC is Pending when no volume has been created for it yet. Each section below covers one cause, with a short fix and a link to the page that explains it in full.

To find the cause, read the events at the end of the output:

				$ kubectl describe pod <pod-name>
$ kubectl describe pvc <pvc-name>
			

Pod is Pending 

Not enough CPU or memory 

The pod requires more CPU or memory than the nodes have free. The scheduler places pods against a node's allocatable capacity, not its full hardware size.

Add more servers to the pool, see or review the pool's server type and move it to a larger one, see .

No node matches the pod's selector or affinity 

A nodeSelector must match a node label's exact key and value, and so must an In rule in required node affinity. A common miss is selecting a role label with "true": role labels under node-role.kubernetes.io/ use an empty-string value ("").

Match the exact key and value the pool sets, and check which nodes carry it with kubectl get nodes -l <label>. See .

Required anti-affinity asks for more replicas than nodes 

Required host anti-affinity allows at most one matching pod per node. Ask for more replicas than you have nodes and the extras stay Pending.

For plain availability spread, use topology spread constraints instead, and keep required anti-affinity for the strict one-per-node case. See .

A topology spread uses a key no node carries 

A topology spread constraint spreads replicas across groups of nodes that share a label, named in topologyKey. With whenUnsatisfiable: DoNotSchedule, the scheduler uses only nodes that carry that label. If no node has it, no replica can be placed, and all of them stay Pending. To let them run, relax the constraint to ScheduleAnyway. See .

The cluster has only control plane nodes 

Control plane nodes carry a NoSchedule taint, and your workloads do not tolerate it. Add a worker pool to run your workloads. See .

The pod uses the secure runtime 

The secure runtime class needs hardware virtualization, which on Hetzner exists only on bare-metal nodes. With no such node in the cluster, the pod stays Pending instead of falling back to a shared kernel. See .

A GPU pod finds no free GPU 

A GPU pod can only run on a node that has a GPU, and GPUs exist only on specific bare-metal servers. If no node has a GPU, or every GPU is already in use, the pod stays Pending. See .

The pod's volume pins it to one place 

A pod whose volume already exists can only schedule where that volume is. A local volume pins the pod to the server that holds it, and a Hetzner Cloud volume pins it to one Hetzner location. If that server is full, cordoned, or gone, or that location has no room, the pod waits. See .

PVC is Pending 

The PVC is waiting for its first pod 

This is normal. The standard and local-* classes create the volume only once a pod that uses the PVC is scheduled. Schedule a pod that mounts the claim. If the PVC is still Pending after its pod is scheduled, one of the causes below applies. See .

A standard volume for a pod on bare metal 

The standard class provisions Hetzner Cloud volumes, which attach only to cloud worker nodes. A PVC with no storageClassName, for example from a Helm chart, also gets standard, because it is the default class. The PVC event shows no topology key found for node.

Keep the pod on cloud nodes with node affinity or a node selector, or use a local class on bare metal. If the claim is already stuck, a selector alone is not enough: delete the PVC and recreate it. See .

A local volume for a pod on a cloud node 

The local-* classes come from disks inside a bare-metal server. A pod that requests one but is scheduled onto a cloud node leaves the PVC Pending. Keep the pod on bare metal with node affinity or a node selector. See .

No volume group or free space for that disk type 

A local class needs the matching volume group on the server: local-ssd needs vg-ssd, for example. A server with no such group, or with no free capacity left in it, cannot hold the volume. The pod event shows did not have enough free storage.

Prepare that disk type on the server, schedule the pod onto a server that has it, or free space on the pool. See and .

Expected Pending pods 

csi-controller on a cluster without cloud workers 

On a cluster with no Hetzner Cloud workers, the csi-controller pods in kube-system stay Pending. The controller runs only on cloud workers, so it has nowhere to schedule. This is expected and does not affect your workloads.