SSD Nodes Learn Hosting plans →
Guides Matt ConnorBy Matt Connor

Enable nested virtualization in Proxmox VE 9

Nested virtualization in Proxmox VE 9: check kvm_intel or kvm_amd, set nested=1 in modprobe.d, give the VM a host CPU, verify in the guest, or turn it off.

What nested virtualization in Proxmox needs

Enabling nested virtualization in Proxmox VE 9.2 takes two settings. On the host, the nested parameter of the kvm_intel or kvm_amd kernel module must be on. On each VM that should run its own hypervisor, the CPU type must pass the vmx (Intel) or svm (AMD) flag through to the guest, which means CPU type host or a vendor-specific model with the +nested-virt flag. Proxmox VE 9.2, current as of September 2026 and built on Debian 13 with a 7.0 kernel, ships with the module side already on for both vendors, so on most hosts the whole job is the VM setting plus a stop and start.

Nested virtualization means a hypervisor running inside a virtual machine. The physical Proxmox host is level 0. A VM on it is level 1. When that VM runs its own hypervisor, such as KVM (Kernel-based Virtual Machine, the Linux hypervisor Proxmox uses) or a second Proxmox VE, the machines inside it are level 2. The hardware has one set of virtualization extensions, VT-x on Intel or AMD-V on AMD, and only the level 0 kernel can use them directly. So the level 0 kernel has to emulate those extensions for the level 1 guest, and that is what the nested module parameter switches on. Without it the guest CPU has no vmx or svm flag, /dev/kvm never appears inside the guest, and any hypervisor in there falls back to software emulation or refuses to start.

Every command below runs as root on the Proxmox host unless the text says "inside the guest", so there is no sudo. The reverse situation, Proxmox itself running inside a VPS (virtual private server), is covered near the end, because it depends on the hosting provider rather than on you.

Check whether nested virtualization is already on

First find out which vendor module the host uses. Intel CPUs load kvm_intel, AMD CPUs load kvm_amd, and the parameter file lives under a different path for each.

grep -m1 -o -w -E 'vmx|svm' /proc/cpuinfo
lsmod | grep -E '^kvm'

The first line prints vmx on Intel or svm on AMD. The second should list kvm_intel or kvm_amd alongside the shared kvm module. Now read the parameter for your vendor:

cat /sys/module/kvm_intel/parameters/nested   # Intel
cat /sys/module/kvm_amd/parameters/nested     # AMD

On Intel the parameter is a boolean, so the file holds Y or N. On AMD it is an integer, so the file holds 1 or 0. Y or 1 means nested virtualization is on at the module level and you can skip ahead to the VM section. N or 0 means someone turned it off, usually through a file in /etc/modprobe.d/, and the next section turns it back on.

A No such file or directory error means the module is not loaded at all. Either you read the wrong vendor's path, or the module failed to load because VT-x or AMD-V is disabled in the host firmware. Run dmesg | grep -i -E 'kvm|vmx|svm' to see the reason. When firmware has the extension switched off, the kernel logs that virtualization is disabled by the BIOS and refuses to load the module. Fix that in the host UEFI (Unified Extensible Firmware Interface) settings first, because nothing below works without it.

Enable nested virtualization persistently with modprobe.d

A module parameter set on the command line lasts until the next reboot. The persistent place is a file in /etc/modprobe.d/, which modprobe reads every time it loads the module. Proxmox's own wiki names the files kvm-intel.conf and kvm-amd.conf. The name does not matter, only the .conf suffix and the options line inside.

Intel:

echo "options kvm-intel nested=1" > /etc/modprobe.d/kvm-intel.conf

AMD:

echo "options kvm-amd nested=1" > /etc/modprobe.d/kvm-amd.conf

Two details in those lines cause most of the confusion. modprobe treats hyphens and underscores in module names as the same character, so kvm-intel and kvm_intel both work in this file. The value is the part to watch. The Intel parameter is a boolean and accepts Y or 1. The AMD parameter is an integer and accepts digits only, so nested=Y for kvm-amd makes the kernel reject the parameter and the module fails to load with an invalid argument error. A host with no kvm_amd module cannot start a single VM. 1 is valid for both vendors, so use 1 everywhere.

Debian copies /etc/modprobe.d/ into the initramfs, the small early-boot filesystem, and on some hosts the vendor module is loaded from there before the real root is mounted. Rebuild the initramfs so both copies of the file agree:

update-initramfs -u -k all

On a host that boots through proxmox-boot-tool, the refresh of the boot partitions runs as a hook of that command, so ZFS-root and systemd-boot installs need no separate step.

Reload the module without rebooting

The new option applies the next time the module loads. A host reboot does that. To skip the reboot, unload and reload the module by hand. The module cannot be unloaded while any VM holds /dev/kvm open, so every VM on the host must be stopped first.

qm list

Every VM should show stopped in the status column. Shut down the ones that are running with qm shutdown <vmid>, then reload the module for your vendor and read the parameter again:

modprobe -r kvm_intel && modprobe kvm_intel   # Intel
modprobe -r kvm_amd && modprobe kvm_amd       # AMD
cat /sys/module/kvm_intel/parameters/nested

If a VM was still running, modprobe -r stops with modprobe: FATAL: Module kvm_intel is in use and nothing changes, so the parameter still reads the old value. Containers are not the problem here. LXC (Linux Containers) share the host kernel and never open /dev/kvm, so they keep running through the reload.

The last line should now print Y on Intel or 1 on AMD. If it still prints the old value, look for another file in /etc/modprobe.d/ that also sets nested:

grep -r nested /etc/modprobe.d/
modprobe -c | grep nested

modprobe -c prints the combined configuration exactly as modprobe will apply it. Options for one module are combined in alphabetical file order and the kernel applies them in that order, so the last value wins. A leftover zz-nested-off.conf from an earlier admin quietly overrides your new file.

Give the VM a CPU that carries vmx or svm

The module setting only makes nesting possible. Each VM still has to be given a virtual CPU that includes the flag. The default type the Proxmox web interface picks for a new VM is x86-64-v2-AES, a generic model designed for live migration between different machines, and it deliberately leaves the virtualization extensions out. To see which VMs already pass the flag, run grep -l 'cpu: host' /etc/pve/qemu-server/*.conf on the host.

The simplest option is CPU type host, which passes the host CPU's whole feature set through, vmx or svm included:

qm set <vmid> --cpu host

The same setting is under Hardware, then Processors, in the web interface.

Since Proxmox VE 9.1 (November 2025) there is a second option for people who want to keep a named CPU model. The nested-virt flag is a shorthand that turns into vmx on an Intel host and svm on an AMD host:

qm set <vmid> --cpu EPYC-Milan,flags=+nested-virt

The 9.1 release notes are specific about the limit: the flag only works on a vCPU (virtual CPU) type that matches the host vendor and generation, and adding it to a generic x86-64-v3 type is not enough. Pick the named model that matches your host CPU, or the closest older one from the same vendor. Custom CPU models in /etc/pve/virtual-guest/cpu-models.conf can also carry +vmx or +svm in their flags line, but host covers almost every homelab.

Whichever you pick, the VM has to be stopped and started for the change to take effect. A CPU model is fixed when QEMU, the emulator process behind each VM, starts, so a reboot triggered from inside the guest keeps the old CPU. Restart it from the Proxmox side:

qm shutdown 100   # your VM's ID
qm start 100

Until you do, qm pending <vmid> lists the new cpu line as a pending change and the running guest still has no vmx or svm flag.

One trade-off to know before you switch a whole cluster over: Proxmox documents that a VM exposing vmx or svm cannot be live-migrated, and CPU type host on its own already ties the VM to hosts with the same CPU model. Plan for those VMs to move offline. If that overhead is what makes you question running a cluster at all, the Proxmox versus a plain VPS comparison weighs it against just renting the VMs.

Confirm from inside the guest

Log into the level 1 guest and check what the virtual CPU advertises:

grep -c -E 'vmx|svm' /proc/cpuinfo
lscpu | grep -i -E 'virtualization|hypervisor'

The grep -c count should equal the number of vCPUs, one match per core. Zero means the flag is not there, so the VM is still on a CPU type without it, or it has not been restarted since the change. lscpu should show a Virtualization: line reading VT-x or AMD-V next to a Hypervisor vendor: line reading KVM. That combination is exactly what you want: a virtual machine that also has virtualization extensions.

Then load KVM inside the guest and make sure the device node appears:

modprobe kvm_intel   # or kvm_amd
ls -l /dev/kvm

On Debian or Ubuntu guests the cpu-checker package adds kvm-ok, which runs the same checks and prints a plain sentence about whether KVM acceleration can be used:

apt install -y cpu-checker
kvm-ok

If the guest is a second Proxmox VE, its installer performs this check on its own and warns during setup when hardware-accelerated KVM is not detected. A nested Proxmox that installed without that warning is ready to run level 2 VMs with the normal kvm: 1 default. A Windows guest is in the same situation: Hyper-V, WSL 2 (Windows Subsystem for Linux), Windows Sandbox and virtualization-based security all need the flag, and CPU type host is the reliable way to give it to them.

Expect level 2 machines to be slower than the same VM on bare metal. Every exit from the level 2 guest passes through two hypervisors, so workloads heavy on interrupts and I/O pay the most. Second-level address translation (ept on Intel, npt on AMD, visible in /proc/cpuinfo on the host) keeps the memory side of that cost low, and every server CPU from the last decade has it. Nested virtualization is for labs and CI (continuous integration) runners, which is the same set of jobs it is good for when the outer layer is a rented VPS instead of your own host.

Disable nested virtualization again

Turning it off is the same file with a different value, plus the same reload. The one trap: on Proxmox VE 9 the kernel default is on, so deleting the file does not disable anything. You have to write 0 explicitly.

echo "options kvm-intel nested=0" > /etc/modprobe.d/kvm-intel.conf   # Intel
echo "options kvm-amd nested=0" > /etc/modprobe.d/kvm-amd.conf       # AMD
update-initramfs -u -k all

Stop every VM, then run modprobe -r kvm_intel && modprobe kvm_intel (or the kvm_amd pair), or reboot the host. cat /sys/module/kvm_intel/parameters/nested should now print N on Intel, and the kvm_amd file should print 0.

VMs with CPU type host pick the change up on their next start, because KVM stops advertising vmx or svm to QEMU once nesting is off, so host no longer includes it. VMs that carry an explicit flags=+nested-virt are asking for a feature the host no longer offers. Remove the flag from their config with qm set <vmid> --cpu <model> so the config and the host agree. Any hypervisor running inside those guests loses acceleration at that restart, which is usually the point of disabling it: fewer VMs that can run their own VMs, and VMs that can be live-migrated again.

Running Proxmox itself inside a VPS

The reverse case is more common than you might expect. People install Proxmox VE on a rented VPS to get a web UI, snapshots, backups and a cluster to learn on. That VPS is already a virtual machine, so the Proxmox you install is a level 1 hypervisor, and every VM you create in it is level 2. It only works when the provider's host has done the same two things for your VPS: nested on in their kernel module, and a CPU type that passes vmx or svm through.

You cannot change that from inside the VPS. You can only check it, with the same command as the guest check above:

grep -c -E 'vmx|svm' /proc/cpuinfo

Zero means the provider does not expose the extensions. Proxmox still installs there, but qm start fails with KVM virtualisation configured, but not available. Either disable in VM configuration or enable in BIOS. and there is no BIOS you can reach. The workaround is qm set <vmid> --kvm 0, which runs the VM under TCG (Tiny Code Generator), QEMU's software emulator. It boots, and it is many times slower than an accelerated VM, so it is fine for testing an installer and useless for a workload. Containers are the honest alternative on such a VPS. An LXC container is a set of processes on the host kernel. It needs no /dev/kvm and runs at native speed, which is the distinction the KVM versus Xen versus LXC comparison spells out in detail. Nested virtualization is only for the VM half of Proxmox.

Not every Proxmox product needs nesting either. Proxmox Backup Server is a Debian service that stores and verifies backups, so running Proxmox Backup Server on a VPS works on any plan, and a homelab often pairs an on-premises Proxmox host with an off-site backup server this way. When the goal really is Proxmox VE with accelerated VMs on rented hardware, pick a provider that documents nested virtualization as a feature rather than one where it happens to work today, because a host migration on their side can remove the flag without notice.

FAQ

How do I check if nested virtualization is enabled in Proxmox?

On the host, run cat /sys/module/kvm_intel/parameters/nested on Intel or cat /sys/module/kvm_amd/parameters/nested on AMD. Y or 1 means the module side is on; N or 0 means it is off. That is only half the check. The VM also needs CPU type host or a vendor model with flags=+nested-virt, and grep -c -E 'vmx|svm' /proc/cpuinfo inside the guest must return a number above zero.

Why does the guest still not show vmx or svm after I enabled nested?

The VM is running on a CPU model that does not include the flag, or it has not been fully restarted since the change. The default x86-64-v2-AES type leaves virtualization extensions out on purpose. Run qm set <vmid> --cpu host, then stop and start the VM from Proxmox. A reboot from inside the guest keeps the old CPU because the model is fixed when the QEMU process starts. qm pending <vmid> shows whether the CPU change is still waiting.

Does nested virtualization stop live migration in Proxmox?

Yes, for the VMs that use it. Proxmox documents that a VM exposing vmx or svm cannot be live-migrated, and CPU type host already limits a VM to hosts with an identical CPU. Move those VMs offline, or keep nesting to a few lab VMs and leave production VMs on a generic CPU type.

Can I run Proxmox VE inside a VPS?

Only when the provider exposes the virtualization extensions to your VPS, which you can check with grep -c -E 'vmx|svm' /proc/cpuinfo before installing anything. Without them, Proxmox installs and its web interface works, but every VM either fails to start with a KVM-not-available error or has to run under software emulation with kvm: 0. LXC containers work either way.

Is it safe to leave nested virtualization on?

For a homelab, yes, and Proxmox VE 9 ships with it on by default. The cost is a larger attack surface inside each guest that uses it, since the guest now drives the host's emulation of the virtualization extensions, and the loss of live migration for those VMs. Disable it with nested=0 in /etc/modprobe.d/ when neither is acceptable. Deleting the file is not enough, because the kernel default is on.