Diagnosing Harvester VM Startup Failures Caused by Resource Constraints
Step‑by‑step diagnostic guide for Harvester VMs stuck in Pending/Creating due to CPU, memory, quota, taints, missing KubeVirt agent, or storage‑class issues.
28 Nov 2025, 19:33 UTC

Recognizable condition
A virtual machine (VM) in Harvester stays in the Pending or Creating phase and never reaches Running. You can see this in the Harvester UI or by running kubectl get virtualmachine -n harvester-system.
Cause/diagnostic table
| Possible cause | What to look for |
|---|---|
| Insufficient host CPU or memory | Nodes show low allocatable resources; VM requests exceed what is free. |
| Overcommitted resource quotas | Namespace or cluster quota limits are hit. |
| Node taints or tolerations blocking scheduling | Scheduler events indicate TaintToleration failures. |
| Missing KubeVirt agent | KubeVirt pods in harvester-system are not ready. |
| Storage class not bound | PersistentVolumeClaim remains Pending with StorageClass not found. |
Ordered checks
- Check node resource availability
Run this command on a workstation with
kubectlconfigured for the Harvester cluster (requires cluster‑admin or harvester‑admin role):
Look for thekubectl describe nodesAllocatableandCapacitylines under CPU and Memory. If theAllocatablevalues are low or show0for the resources your VM requests, the node is exhausted.Risk: Misinterpreting
Allocatableafter a node drain can lead to unnecessary scaling. - Review the VM spec requests/limits
Retrieve the VM definition (replace
<vm-name>and<namespace>with your values):
Examine thekubectl get virtualmachine <vm-name> -n <namespace> -o yamldomain.resources.requestsblock forcpuandmemory. Compare these numbers to the free resources you observed in step 1. - Inspect Harvester/KubeVirt controller logs
Controller logs often contain the scheduling reason. Use:
andkubectl logs -n harvester-system deployment/harvester-network-controller
Search for phrases likekubectl logs -n harvester-system deployment/kubevirt-controllerFailedSchedulingorInsufficient cpu. - Verify storage class and volume binding status
Check the PVC associated with the VM’s disk:
Then describe it:kubectl get pvc -n <namespace> -l kubevirt.io=domain-name,<vm-name>
If thekubectl describe pvc <pvc-name> -n <namespace>Eventssection showsStorageClassnot found orWaiting for first consumerwithout binding, the storage class is the issue. - Look for scheduling events
Describe the VM to see events emitted by the scheduler:
In thekubectl describe virtualmachine <vm-name> -n <namespace>Eventstable, note anyFailedSchedulingreasons (e.g.,NodeAffinity,TaintToleration,Insufficient cpu).
Fixes tied to findings
- Add or resize nodes – If node CPU/memory is insufficient, add a new node to the cluster or increase the size of existing nodes (requires infrastructure access). After adding, run
kubectl get nodesto confirm the new node appears withReadystatus. - Adjust VM resource requests – Edit the VM spec to lower requests to match available resources:
Changekubectl edit virtualmachine <vm-name> -n <namespace>cputo a value ≤ free CPU cores andmemoryto ≤ free memory (e.g., from4vCPU to2vCPU). Save and exit; the controller will reschedule. - Remove conflicting taints/tolerations – If a node taint blocks the VM, either remove the taint or add a matching toleration to the VM:
or edit the VM to addkubectl taint nodes <node-name> key=value:NoSchedule-tolerations:block. - Ensure KubeVirt agent is running – Restart the KubeVirt controller pod if it is CrashLoopBackOff:
Verify pods arekubectl rollout restart deployment/kubevirt-controller -n harvester-systemReadywithkubectl get pods -n harvester-system. - Bind or create appropriate storage class – If the PVC lacks a bound storage class, create one that matches your backend (e.g., Longhorn) or use the existing
harvester-longhornclass:
Then patch the PVC:kubectl get storageclass
Warning: Changing the storage class of an existing volume may detach it; ensure you have a snapshot or backup first.kubectl patch pvc <pvc-name> -n <namespace> -p '{"spec":{"storageClassName":"harvester-longhorn"}}' - Restart Harvester controller if needed – After fixing the above, a controller restart can clear stale state:
kubectl rollout restart deployment/harvester-network-controller -n harvester-system
Escalation criteria
- If the VM remains
Pendingafter applying the relevant fix and the logs show no clear scheduling error, collect a full log bundle: kubectl get events -n harvester-system > events.txtkubectl logs -n harvester-system -l app=harvester --all-containers > controller.logs- Open a support ticket with Harvester, attaching the bundle and the VM YAML.
- Check the Harvester release notes for known issues matching your version (e.g., v1.2.0) before filing a bug.
Verification
- After applying a fix, run
kubectl get virtualmachine <vm-name> -n <namespace>and confirm theSTATUScolumn showsRunning. - Check node utilization to ensure you are not over‑committing:
kubectl top nodesor view the Harvester dashboard; aim for CPU and memory usage below 80 % on each node. - Run
kubectl get events -n harvester-systemand verify that noFailedSchedulingevents persist for the VM.
Limitations
- This guide assumes Harvester ≥ 1.0 with KubeVirt enabled.
- It does not cover hardware‑level failures (e.g., CPU throttling due to overheating) or network‑related startup issues.
- Storage‑class changes are risky; always snapshot volumes before modification.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.