If you’re looking for VirtIO drivers, you need one of two files from the Fedora virtio-win project. The virtio-win ISO is what Windows Setup needs before it can see a VirtIO disk, and virtio-win-gt-x64.msi installs every driver on a Windows VM that already boots. You do not have to hunt for a version number either, because the stable links redirect to the current build. Which file you grab depends on one question: is Windows already installed on the VM, or not yet?
The direct download links come first. After them you’ll see how to install VirtIO drivers on Windows in each case you can hit: loading the storage driver during Setup, the MSI and the guest tools on a running VM, and moving an existing SATA VM onto VirtIO without an INACCESSIBLE_BOOT_DEVICE crash. Two results surprised us, so they’re called out where they bite. We checked every link and ran every install path in October 2026 against virtio-win 0.1.302 on Windows 11 and Windows Server 2025 VMs on Proxmox VE.
1. Download the virtio-win ISO and MSI
All four files sit in one folder on fedorapeople.org, and the stable-virtio path is the one to bookmark. Every file there is a redirect to the newest stable build, so a script or a wiki page that points at it never goes stale. When we checked, the stable and latest channels both resolved to the same build. The table shows what each file installs and when you’d pick it.
| File | What it installs | Size (0.1.302) | Use it when |
|---|---|---|---|
virtio-win.iso | Every driver for every Windows release, plus the installers below | 837 MiB | Windows isn’t installed yet, or the VM has no network |
virtio-win-gt-x64.msi | Drivers only (64-bit) | 4.7 MiB | Golden images, scripted installs, upgrades |
virtio-win-gt-x86.msi | Drivers only (32-bit) | 2.6 MiB | Old 32-bit guests |
virtio-win-guest-tools.exe | Drivers, QEMU guest agent, SPICE agent | 30 MiB | A VM that already boots and has a network |
These are the direct links you can paste into a browser, wget or curl. Each one answers with a 301 to the build’s archive folder, so pass -L when you use curl.
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win-gt-x64.msi
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win-guest-tools.exe
On a Proxmox host, pull the ISO straight into the default ISO store so it shows up in the CD/DVD picker. If you run KVM with libvirt, use /var/lib/libvirt/images instead, because that’s where virt-manager looks for installation media.
cd /var/lib/vz/template/iso
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso
file virtio-win.iso
The file check reads the volume label, and that label carries the build number. It’s the quickest way to tell which release a disc holds when you find it in your ISO store six months from now.
virtio-win.iso: ISO 9660 CD-ROM filesystem data 'virtio-win-0.1.302'
If you want to see where the latest-virtio channel points before you download 837 MiB, follow the redirects with a HEAD request.
curl -sIL https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso | grep -iE '^(HTTP|Location|Content-Length)'
Two hops land on the versioned file in archive-virtio, and the final 200 carries the same byte count as the stable ISO.
HTTP/1.1 301 Moved Permanently
Location: http://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.302-1/virtio-win.iso
HTTP/1.1 301 Moved Permanently
Location: http://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.302-1/virtio-win-0.1.302.iso
HTTP/1.1 200 OK
Content-Length: 877373440
Today latest points at the same 0.1.302 build the stable channel serves, so there is no reason to run latest on production guests. When the two channels do split, latest is where new builds land first, and you’d only want it to test a fix you are waiting for.
Invoke-WebRequest downloads “Making sure you’re not a bot!” instead of the MSI
Downloading from inside Windows has one trap. fedorapeople.org now sits behind a bot challenge that inspects the User-Agent, and PowerShell’s Invoke-WebRequest sends a browser-style one. On our Server 2025 VM it saved a 4,447-byte HTML page called “Making sure you’re not a bot!” under the MSI’s name, exited cleanly, and left a file that msiexec cannot open. The curl.exe built into Windows 11 and Server 2025 was not challenged and fetched the real file in 3 seconds, so use it instead.
New-Item -ItemType Directory -Force C:\lab
curl.exe -L -o C:\lab\virtio-win-gt-x64.msi https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win-gt-x64.msi
Get-Item C:\lab\virtio-win-gt-x64.msi | Select-Object Name, Length
Check the size before you run anything. A real MSI is 4,887,552 bytes, so a file of a few KB is the challenge page, and you should delete it before a script tries to install it.
Name Length
---- ------
virtio-win-gt-x64.msi 4887552
Neither installer carries an Authenticode signature (Get-AuthenticodeSignature reports NotSigned for both the MSI and the guest tools EXE). The drivers inside are a different story: their catalogs and every bound driver report the Microsoft Windows Hardware Compatibility Publisher as signer, so Windows loads them without test-signing tricks. The unsigned wrappers matter more than they look, because the stable links redirect to a plain http:// URL (you can see it in the Location lines above) and the project publishes no hash for the ISO, MSI or EXE. If you want the whole transfer over TLS, request the archive path directly with https://, for example https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.302-1/virtio-win-gt-x64.msi, and never take these files from a mirror or a forum attachment.
2. Pick Your Install Path
Start from the state your VM is in right now, not from which file you already downloaded. Each case has one right tool, and picking the wrong one is how people end up in the Windows recovery screen. Find your VM in this list:
- Windows isn’t installed yet and the disk is VirtIO: attach the ISO as a second CD and load
vioscsiat the disk screen (section 4), then run the guest tools after first login. - The VM boots and has a network: run
virtio-win-guest-tools.exeonce. It’s the driver MSI plus the QEMU guest agent and SPICE agent, and it took 11 seconds on our Server 2025 VM. - You build templates or push installs with a script: the MSI with
msiexec /qn, because it installs drivers only and upgrades an older build in place. - The VM boots from SATA or IDE today: install the drivers first, bind the SCSI driver with a throwaway disk, and only then move the boot disk (section 8). This is the usual state of a VM imported from VMware or Hyper-V.
For most people the guest tools EXE is the whole answer, because a Windows VM without the guest agent cannot report its IP to Proxmox, freeze its filesystem for consistent backups, or take shutdown requests through the agent. We’d only reach for the bare MSI where something else already manages the agent, such as a template pipeline that installs qemu-ga-x86_64.msi as its own step. If you are unsure which case you’re in, run Get-Disk in the guest: a SATA bus type puts you in the last one.
3. Check What the ISO Contains
The virtio-win package holds one folder per device driver, and each folder has a subfolder per Windows release. Knowing that layout saves you guessing at the Setup driver screen later. Listing the vioscsi folder on the mounted 0.1.302 disc (drive F: on our Windows 11 VM) shows how far back the support goes.
(Get-ChildItem F:\vioscsi -Directory).Name -join ' '
(Get-ChildItem F:\vioscsi\w11 -Directory).Name -join ' '
Server releases use the 2kNN names and desktop releases the wNN names. The Windows 11 folder carries both x64 and ARM64 builds, so the same disc covers an Arm guest too.
2k12 2k12R2 2k16 2k19 2k22 2k25 2k8 2k8R2 w10 w11 w7 w8 w8.1
ARM64 amd64
Only a handful of those folders matter on a typical VM. The table lists the ones our two lab VMs actually bound, plus the two you might add later.
| Folder | Driver for | Shows up in Windows as |
|---|---|---|
vioscsi | virtio-scsi disks (the Proxmox default controller) | Red Hat VirtIO SCSI pass-through controller |
NetKVM | VirtIO network card | Red Hat VirtIO Ethernet Adapter |
Balloon | Memory ballooning | VirtIO Balloon Driver |
vioserial | The channel the QEMU guest agent talks over | VirtIO Serial Driver |
fwcfg | QEMU firmware config device | QEMU FwCfg Device |
viostor | virtio-blk disks, if you pick VirtIO Block instead of SCSI | not used on our VMs |
viofs | virtiofs shared folders between host and guest | not used on our VMs |
The balloon driver is the one that quietly pays off on a busy host, because it lets the hypervisor reclaim memory from idle Windows guests. If your host was tight on RAM to begin with, the memory sizing guide for Proxmox hosts shows how much headroom Windows guests realistically need.
4. Load the Driver in Windows Setup
A new VM with a VirtIO disk from day one is the right build, but Windows Setup cannot see that disk, because the installer image has no VirtIO storage driver. The fix is a second CD drive holding the virtio-win ISO next to the Windows ISO. In Proxmox you add it under Hardware > Add > CD/DVD Drive.

Pick virtio-win.iso from the ISO storage and confirm. On KVM with virt-manager the same step is Add Hardware > Storage with the device type set to CDROM.

Boot the VM from the Windows ISO and continue to the disk screen. You’ll find the list empty, which is expected and does not mean the disk is broken.

Click Load Driver (the Server 2025 installer titles this screen “Install driver to show hardware”), then Browse, and open the virtio-win CD. The folder you want depends on the disk controller and the Windows release:
- Windows Server 2025 on virtio-scsi:
vioscsi\2k25\amd64 - Windows Server 2022 on virtio-scsi:
vioscsi\2k22\amd64 - Windows 11 on virtio-scsi:
vioscsi\w11\amd64(orARM64on an Arm host) - Any release on a virtio-blk disk: the same release folder under
viostor
Browse into the folder for your release, then its amd64 subfolder. If you keep several virtio-win ISOs in storage, check which one the CD drive points at in the VM’s hardware before you boot, because the dialog won’t tell you the build.

Setup scans the folder and offers the driver it finds there, the Red Hat VirtIO SCSI pass-through controller for a virtio-scsi disk.

Select it and click Install. A few seconds later the disk appears and installation carries on as normal.

These Setup screens come from our earlier Server 2025 run with the previous build. The folder layout on the 0.1.302 disc is the same, which we confirmed by listing it in section 3. You can load NetKVM from the same dialog if you want a network during the out-of-box screens, but it’s simpler to finish Setup and run the guest tools from the desktop. Full walkthroughs of the rest of the install live in our guides to Windows Server 2025 on KVM and Windows 11 with virt-manager, and Windows 11 also needs a vTPM, which the TPM on KVM guide covers.
5. Install VirtIO Drivers on Windows With the MSI
virtio-win-gt-x64.msi installs every driver on a running VM and upgrades an older virtio-win in place. Double-clicking it on the mounted CD gives you the classic feature wizard. Leave every feature selected unless you have a reason not to, because a driver you skip now is a device that shows up unknown after the next hardware change.

For templates and scripted builds, run it silently from an elevated PowerShell. Keep the verbose log, because it is the only place the installer tells you whether a reboot is pending.
$p = Start-Process msiexec.exe -ArgumentList '/i C:\lab\virtio-win-gt-x64.msi /qn /norestart /l*v C:\lab\virtio-msi.log' -Wait -PassThru
$p.ExitCode
Exit code 0 means success. Our Server 2025 template still carried the previous 0.1.285 build, and the MSI replaced it in 27 seconds while our remote PowerShell session over the guest agent kept answering. This was the driver list before the upgrade.
DeviceName DriverVersion
---------- -------------
QEMU FwCfg Device 100.101.104.28500
Red Hat VirtIO SCSI pass-through controller 100.101.104.28500
Red Hat VirtIO Ethernet Adapter 100.101.104.28500
VirtIO Serial Driver 100.101.104.28500
Run the same query straight after the MSI, with no reboot in between, and every device has moved. The trailing 30200 is the 0.1.302 build.
DeviceName DriverVersion
---------- -------------
QEMU FwCfg Device 100.103.104.30200
Red Hat VirtIO SCSI pass-through controller 100.103.104.30200
Red Hat VirtIO Ethernet Adapter 100.103.104.30200
VirtIO Serial Driver 100.103.104.30200
That list shows the driver package Windows has assigned to each device, not proof that the new binary is already loaded. The log still asked for a restart (UninstallPackages: Reboot requested.), and /norestart held it back, so treat the new build as registered and fully in effect only after the reboot. On the Windows 11 VM, which still booted from SATA with an e1000 NIC, the same MSI from the mounted ISO took 2 minutes 30 seconds, and the VirtIO Serial Driver dropped out of the device list until the next boot. That is the driver the guest agent rides on, so schedule the reboot rather than skipping it. We’d do it as a shutdown and start from Proxmox rather than a restart inside Windows, because pending VM hardware changes and the guest agent option only take effect when the VM process itself starts again.
6. Install the QEMU Guest Agent
virtio-win-guest-tools.exe is the one-pass installer. It runs the driver MSI for your architecture, then adds the QEMU guest agent and the SPICE agent, so you get drivers and agent in a single run. On the mounted CD it sits in the root next to the driver folders. Our 2024 screenshot shows an older disc in Explorer, and the 0.1.302 disc has the same layout with the same installer names.

Double-click it and accept the license to run it interactively. It is a WiX bundle, so it also takes the standard quiet switches. This is the command we ran on Server 2025 after downloading the EXE with curl.exe.
Start-Process C:\lab\virtio-win-guest-tools.exe -ArgumentList '/install /quiet /norestart /log C:\lab\gt.log' -Wait
The log records each package and how it went. All three applied in 11 seconds, and the last line confirms nothing forced a restart.
[01D4:054C][2026-10-30T00:48:41]i319: Applied execute package: vwi.TXYS, result: 0x0, restart: None
[01D4:054C][2026-10-30T00:48:42]i319: Applied execute package: vwi.0n2u, result: 0x0, restart: None
[01D4:054C][2026-10-30T00:48:50]i319: Applied execute package: vwi.JlI2, result: 0x0, restart: None
[01D4:054C][2026-10-30T00:48:50]i007: Exit code: 0x0, restarting: No
The guest agent moved from 110.0.2 to 110.2.3 and the SPICE agent came along at 0.10.5. One trap if you automate this is to launch the guest tools through the guest agent itself (qm guest exec or anything built on it). The bundle replaces the QEMU guest agent package halfway through, and the session that launched it did not survive that on our VM: our wrapper never wrote its “done” marker, although the log shows the install finished. Push it over WinRM, RDP or a scheduled task instead.
On the Proxmox side, turn the agent on under Options > QEMU Guest Agent if it is not already, then use Shutdown followed by Start (not the Stop button highlighted below, which powers the VM off immediately). When the agent answers, the VM summary shows the guest’s IPs. The order matters: with the option on but no agent running in Windows, a shutdown from Proxmox waits for an agent that never replies and times out.

If you only want the agent, the disc also carries guest-agent\qemu-ga-x86_64.msi on its own. Build Windows VMs often? Do this once and turn the result into a template, which the Windows Server template guide for Proxmox walks through.
7. Check the Drivers Are Active
One PowerShell query lists every Red Hat driver Windows has bound, with its version. Every device should report the same build, because a mixed list means an upgrade only half finished and the odd one out will be replaced at the next reboot anyway. The section 5 output is what a clean result looks like.
Get-CimInstance Win32_PnPSignedDriver | Where-Object { $_.Manufacturer -like '*Red Hat*' } | Select-Object DeviceName, DriverVersion
Check the agent service while you are in the same shell.
Get-Service QEMU-GA, BalloonService
Both should be running. On our Windows 11 VM the VirtIO Serial Driver only came back after a reboot, so if the agent stops answering right after an install, cold start the VM before you debug anything else.
Status Name DisplayName
------ ---- -----------
Running BalloonService BalloonService
Running QEMU-GA QEMU Guest Agent
Then confirm the disk and NIC really sit on the paravirtual devices, not on emulated hardware. Installing a driver does not move a device onto it, so this is the check that tells you whether the VM is actually faster.
Get-Disk | Select-Object Number, FriendlyName, BusType, Size
Get-NetAdapter | Select-Object Name, InterfaceDescription, LinkSpeed
Our Server 2025 VM, already on VirtIO, returned this.
Number FriendlyName BusType Size
------ ------------ ------- ----
0 QEMU QEMU HARDDISK SAS 68719476736
Name InterfaceDescription LinkSpeed
---- -------------------- ---------
Ethernet Red Hat VirtIO Ethernet Adapter 10 Gbps
Read those two tables against what each device should report on a fully converted VM:
- Disk bus type
SAS: that’s virtio-scsi as Windows names it.SATAmeans the disk is still on the emulated AHCI controller, and section 8 moves it. - NIC “Red Hat VirtIO Ethernet Adapter” at 10 Gbps: the 10 Gbps is a nominal link speed, not a measurement. “Intel(R) PRO/1000 MT Network Connection” is the emulated e1000, which our Windows 11 VM still used before its conversion.
- QEMU-GA running and the IP visible in the Proxmox summary: the agent and the VirtIO serial channel both work. A running service with no IP in Proxmox means the agent option is off, or was turned on without a Shutdown and Start.
8. Move a SATA VM to VirtIO
This is where people break their VMs. Windows only loads a boot-critical storage driver that is already bound to hardware it has seen, so flipping the boot disk from SATA to VirtIO in one step gets you INACCESSIBLE_BOOT_DEVICE and, after a failed auto-repair, the recovery screen. We hit exactly this in our earlier run.

If you’re already stuck there, move the disk back to SATA and boot, because nothing is damaged. The safe order uses a small throwaway VirtIO disk to make Windows bind the driver first. We ran it on a Windows 11 VM that booted from SATA with an e1000 NIC, with the virtio-win ISO attached and the old vioscsi package removed from the driver store, so it behaved like a VM that has never seen VirtIO. If you already ran the MSI from section 5, the driver is in the store and the controller usually binds by itself, so check Get-Disk for a SAS disk after the hot-add and only reach for pnputil when the controller shows as an error. Set your VM ID and storage once on the Proxmox host (local-lvm on a default install), and print the three lines that matter. Note the volume on the sata0 line, because that is your boot disk.
VMID="4090"
STORAGE="zfs-pool"
qm config ${VMID} | grep -E 'scsihw|sata0|net0'
The scsihw line should read virtio-scsi-single, because older VMs often still use the LSI controller and the dummy disk would then prove nothing (and the iothread=1 option used below only works with the single variant). If yours doesn’t, change it in Hardware > SCSI Controller, then shut the VM down and start it again, because the controller change stays pending until the VM restarts. Ours was already right, so we only hot-added a 1 GB disk to the running VM.
qm set ${VMID} --scsi1 ${STORAGE}:1
Inside Windows, the new controller shows up as an error device with no driver. List the devices in that state from an elevated PowerShell.
Get-PnpDevice -Status Error | Select-Object Status, Class, FriendlyName, InstanceId
Vendor 1AF4 with device 1004 is the VirtIO SCSI controller, and the empty class column means no driver has claimed it yet.
Status Class FriendlyName InstanceId
------ ----- ------------ ----------
Error SCSI Controller PCI\VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00\5&1E249680&0&1020F0
Find the CD’s drive letter first, because it isn’t always D: (ours was F: behind two other CD drives). Then install the driver for your release against the live controller.
Get-Volume | Where-Object DriveType -eq 'CD-ROM' | Select-Object DriveLetter, FileSystemLabel
pnputil /add-driver F:\vioscsi\w11\amd64\vioscsi.inf /install
This is the second surprise. On Server 2025 in our earlier run, pnputil bound the controller live, but on Windows 11 it added the package, exited with code 3010 and asked for a reboot.
Adding driver package: vioscsi.inf
Driver package added successfully.
Published Name: oem10.inf
System reboot is needed to complete install operations!
Total driver packages: 1
Added driver packages: 1
System reboot is needed to complete install operations!
Until that reboot, the controller sat in CM_PROB_NORMAL_CONFLICT and the 1 GB disk stayed invisible, which looks like a failure if you don’t know to restart. After one reboot the controller reported OK and Get-Disk listed the helper disk. That proves the driver is bound and ready to boot from.
Number FriendlyName BusType Size
------ ------------ ------- ----
0 QEMU HARDDISK SATA 68719476736
1 QEMU QEMU HARDDISK SAS 1073741824
Shut Windows down and detach both disks. The boot disk becomes an unused volume, which you re-attach on the VirtIO controller in the next command.
qm set ${VMID} --delete sata0,scsi1
qm config ${VMID} | grep unused
Two volumes now show as unused: the boot disk and the 1 GB helper. Their numbers depend on what the VM had before, so never guess the disk name. Set BOOTVOL to the exact volume from the sata0 line you printed at the start (ours was zfs-pool:vm-4090-disk-1; on another VM it can be disk-0, and that name may belong to the blank helper instead). Then re-add it as scsi0 and make it the boot device.
BOOTVOL="zfs-pool:vm-4090-disk-1"
qm set ${VMID} --scsi0 ${BOOTVOL},discard=on,iothread=1,ssd=1 --boot order=scsi0
Switch the NIC in the web UI under Hardware > Network Device > Edit by changing only Model to VirtIO (paravirtualized). Editing it there keeps the MAC, the bridge, any VLAN tag and the firewall flag, which a hand-typed --net0 line can silently drop. Then start the VM.
qm start ${VMID}
The first qm start after a quick shutdown failed on our host with timeout waiting on systemd, and a second start worked. Windows 11 then took about three minutes to settle on the new controller before the guest agent answered, so give a slow first boot time before you reach for the reset button. It came up on the VirtIO disk and NIC.
Number FriendlyName BusType Size OperationalStatus
------ ------------ ------- ---- -----------------
0 QEMU QEMU HARDDISK SAS 68719476736 Online
Name InterfaceDescription LinkSpeed Status
---- -------------------- --------- ------
Ethernet 2 Red Hat VirtIO Ethernet Adapter 10 Gbps Up
The adapter came back as “Ethernet 2”, a new interface as far as Windows is concerned, so static IP settings on the old “Ethernet” have to be entered again. The 1 GB helper is still on the VM as an unused volume. Deleting an unusedN entry destroys that volume, so list the unused entries first and confirm the one you remove names the volume that was on scsi1, not your boot disk. On our VM it was unused1.
qm config ${VMID} | grep unused
Our VM listed only the helper, unused1: zfs-pool:vm-4090-disk-3, so that is the entry we deleted.
qm set ${VMID} --delete unused1
If the VM you’re converting still lives on VMware, the ESXi to Proxmox migration guide folds this driver work into the move, and on a plain KVM/QEMU host the same ISO and the same order apply: driver first, dummy disk, then the boot disk.
Where Each Path Falls Short
None of the four paths is free of catches, and the catches decide which one you can live with.
- Guest tools EXE: the simplest path, but it replaces the guest agent mid-run, so don’t push it through that agent, and it installs the SPICE agent whether you use SPICE or not.
- Driver MSI: clean for templates and upgrades, but drivers only. Pair it with
qemu-ga-x86_64.msior Proxmox loses IP reporting, agent-driven shutdown and filesystem freeze for backups. - Load Driver in Setup: gets Windows onto a VirtIO disk from the start, but it only loads storage. You still run the MSI or EXE after first login.
- SATA to VirtIO swap: the only safe way to convert a running VM, but it costs at least two reboots and a new network interface name. Plan it for a maintenance window, not a lunch break.
If you only pick one, make it the guest tools on any VM that already has a network, and keep the ISO in your storage for the days you need the Setup driver or a VM that has no network yet.