Hyper-V Memory Balloon Fails: 3 Causes & Fixes
Memory ballooning in Hyper-V fails when dynamic memory can't reclaim RAM. Three main causes: locked pages, misconfigured limits, or driver issues.
1. Locked Pages in the VM Are Blocking the Balloon
Memory ballooning works by the hypervisor asking the guest OS to release pages. But if apps inside the VM have locked memory (via VirtualLock or similar), the balloon driver can't touch those pages. The hypervisor sees zero freeable memory and fails silently.
I see this most often with SQL Server or custom apps that call VirtualAlloc(MEM_RESERVE | MEM_COMMIT | MEM_PHYSICAL) . Also any process with “Lock pages in memory” user right (often given to SQL Server service accounts) will hold pages pinned.
- Open Task Manager inside the VM, go to Performance > Memory, and look at “Hardware Reserved” or “Non-paged pool”. If non-paged pool is high (over 1 GB), you have locked pages.
- Run
!vm 3in the VM's kernel debugger (kd) to see locked page count. Or usepoolmon.exefrom Windows SDK to find the tag. - Fix: Remove “Lock pages in memory” from any unnecessary accounts via gpedit.msc or secpol.msc. For SQL Server, you can keep it but limit memory via
sp_configure 'max server memory'. - Reboot the VM to release the locks, then test ballooning by adding memory pressure (run a memory-heavy script or
Test-VMReplicationwith -MemoryPressure).
The reason step 4 works is that a fresh boot clears all page pins from the previous session. After that, the balloon driver sees free pages and works.
2. Dynamic Memory Limits Are Set Too Tight
Hyper-V dynamic memory has a startup RAM, min RAM, and max RAM. If min RAM equals max RAM, or the gap is tiny (e.g., 4 GB min, 4.5 GB max), the balloon has almost no room to shrink. The hypervisor tries to reclaim, but the VM's configured minimum is already close to the physical allocation.
Real trigger: You set up a VM with 8 GB startup, 4 GB min, 8 GB max. VM boots and uses 5 GB. Balloon tries to reclaim 3 GB back to host. But the min is 4 GB, so only 1 GB is reclaimable. If the host needs 2 GB, balloon fails.
- Check the VM's dynamic memory settings in Hyper-V Manager or via PowerShell:
Get-VM -Name 'YourVM' | Select-Object MemoryStartup, MemoryMinimum, MemoryMaximum. - Ensure
MemoryMinimumis at least 50% ofMemoryStartup, but not more than 80%. For example, startup 8 GB, min 4 GB is good. Startup 8 GB, min 7 GB is bad. - Widen the gap: Set min to 50% of startup. For a VM with 8 GB startup, set min to 4 GB, max to 16 GB or more (up to host limits).
- Apply the change (live if the VM is running). Then trigger pressure: run
Stress-NGon Linux orTest-Pressurescript on Windows to force balloon activity.
The reason step 3 works is that the balloon driver only reclaims memory down to the minimum. If the minimum is too high, the balloon can't release enough.
3. Balloon Driver Is Missing or Outdated
Hyper-V installs a synthetic memory balloon driver inside the VM (vmbus.sys, part of Linux Integration Services or Hyper-V Integration Services on Windows). If this driver is old, missing, or replaced by a third-party driver (like from VMware Tools), ballooning won't work.
Real scenario: You migrated a VM from VMware to Hyper-V but forgot to remove VMware Tools. VMware's balloon driver conflicts with Hyper-V's. Or you're running an old Linux kernel (pre-3.10) without proper LIS.
- Inside the VM, check Device Manager (Windows) or
lsmod | grep hv_balloon(Linux). Ifhv_balloonisn't listed on Linux, the module isn't loaded. - On Windows: Install or reinstall “Hyper-V Integration Services” from the VM connection window (Action > Insert Integration Services Setup Disk).
- On Linux: Update LIS. For Ubuntu:
sudo apt install linux-azure(includes Hyper-V drivers). For RHEL/CentOS 7+:sudo yum install microsoft-hyper-v. - Remove any third-party balloon drivers (like VMware's
vmmemctl). Uninstall VMware Tools entirely unless you really need it. - Reboot the VM. After reboot, check
dmesg | grep balloonon Linux or Event Viewer > Windows Logs > Hyper-V-Worker (Event ID 12552 should disappear).
The reason step 5 works is that a reboot loads the correct driver stack. Without it, the old driver conflict remains in memory.
| Cause | Symptom | Fix |
|---|---|---|
| Locked pages inside VM | Non-paged pool > 1 GB, Event ID 12552 | Remove lock pages permission, reboot VM |
| Dynamic memory limits too tight | Balloon never shrinks, host memory pressure | Set min to 50% of startup, widen gap |
| Missing/conflicting balloon driver | hv_balloon not loaded, VMware Tools conflict | Reinstall Integration Services, remove third-party drivers |
Was this solution helpful?