If you're building a TrueNAS or Unraid virtual machine inside Proxmox VE, you'll hit a wall pretty fast: virtual disks work, but they're not what a NAS operating system wants. TrueNAS wants to see real, physical drives so ZFS can manage them directly. Handing it a handful of virtual disks sitting on top of a Proxmox storage pool is technically possible, but it adds a layer of abstraction that causes weird problems during drive failures, SMART monitoring, and pool imports.
The fix is to stop virtualizing the disks altogether and give the VM direct control of the physical storage controller instead. That's what this guide covers — passing an entire SATA or SAS HBA (host bus adapter) card through to a virtual machine in Proxmox VE, so the guest OS talks to the drives exactly as if it were installed on bare metal.
This isn't a five-minute checkbox. It touches your BIOS, your bootloader, your kernel modules, and your VM configuration. Budget about 30 to 45 minutes the first time you do it, plus a couple of reboots. Get it right, though, and TrueNAS or Unraid running inside a VM behaves almost indistinguishably from running on real hardware.
What You Will Learn
- What an HBA is and why it's different from passing through a single disk
- How to enable IOMMU in your BIOS and in Proxmox VE's bootloader
- How to find your controller's PCI address and check its IOMMU group
- How to bind the controller to
vfio-pciso the host leaves it alone - How to attach it to a VM and confirm the guest sees the raw disks
- The errors people run into most often, and how to work through them
What Is HBA Passthrough?
An HBA, or host bus adapter, is the physical card (or onboard chip) that your drives actually plug into — the thing translating between SATA or SAS cabling and your motherboard's PCIe bus. On a lot of desktop boards this is baked into the chipset. On servers and in a lot of homelabs, it's a separate add-in card, often an LSI/Broadcom-based SAS card flashed into "IT mode" so it behaves like a plain HBA instead of a hardware RAID controller.
PCI passthrough is the mechanism that lets Proxmox VE hand a PCIe device to a VM directly, bypassing the host's own drivers entirely. Once you pass through the whole HBA, every drive wired into it disappears from the Proxmox host and shows up inside the guest as a native block device — /dev/sda, /dev/sdb, and so on, exactly as TrueNAS expects.
This is different from passing through one disk at a time using qm set --scsi with a raw device path. Single-disk passthrough still goes through the host's SATA/SAS driver, and it doesn't forward things like SMART data or drive serial numbers reliably. Controller passthrough skips all of that — the guest owns the hardware, full stop.
Why Would You Use It?
The honest answer is: because ZFS wants to own its disks. TrueNAS Scale and TrueNAS Core both lean on ZFS, and ZFS was designed assuming direct access to real drives — no RAID controller lying about geometry, no virtualization layer hiding SMART attributes or reordering writes. When a drive dies, you want TrueNAS to see that immediately and clearly, not have it hidden behind a virtual disk that still looks "healthy" to the VM.
There's a practical angle too. If you ever want to move that TrueNAS install to different hardware, or boot it bare-metal for troubleshooting, ZFS can import the pool right away because the physical disks were never touched by anything except TrueNAS. Compare that to virtual disks stored in a Proxmox-managed format — untangling that later is a genuinely bad afternoon.
I'll add an opinion here: don't bother passing through individual disks one at a time if you have more than two or three. It's more fragile, and every new drive means editing the VM config again. Pass through the whole controller once and add drives to it physically from then on — Proxmox never needs to know they exist.
Prerequisites
Before you touch any configuration, make sure the following are true:
- Your CPU and motherboard support hardware virtualization with IOMMU — Intel VT-d or AMD-Vi. Almost anything from the last decade does, but cheap consumer boards sometimes disable it in BIOS by default.
- You're running a dedicated HBA card, ideally one flashed to IT mode (LSI 9207-8i, 9300-8i, and similar are common homelab picks), or you're comfortable working with your onboard SATA controller if it's isolated in its own IOMMU group.
- The controller you're passing through is not the one your Proxmox boot drive is connected to. If it is, you'll lose access to your own host operating system the moment the VM claims the card. Use a separate controller, or boot Proxmox from NVMe/USB and dedicate the HBA entirely to the guest.
- You have root shell access to the Proxmox host, either via SSH or the web console.
- Proxmox VE 8.x or 9.x installed (the steps here are the same across both).
Step-by-Step Tutorial
1. Enable IOMMU in your BIOS
Reboot into your BIOS/UEFI setup and look for a setting called VT-d (Intel) or AMD-Vi / IOMMU (AMD), usually under an "Advanced" or "Chipset" menu. Enable it and save. On some boards this is labeled just "IOMMU" with no vendor name attached — turn that on too if you see it alongside VT-d/AMD-Vi.
2. Enable IOMMU in the Proxmox bootloader
Proxmox VE boots with either GRUB or systemd-boot, depending on how it was installed (ZFS-on-root installs typically use systemd-boot). Check which one you're on:
proxmox-boot-tool status
If it lists ESP partitions and says "Bootloader vfat, disk contains initrd, kernel, and cmdline", you're on systemd-boot. Otherwise, you're on GRUB.
For systemd-boot: edit /etc/kernel/cmdline and add the IOMMU flags to the existing line (don't remove what's already there). For Intel CPUs:
root=ZFS=rpool/ROOT/pve-1 boot=zfs intel_iommu=on iommu=pt
For AMD CPUs, use amd_iommu=on iommu=pt instead. Then apply it:
proxmox-boot-tool refresh
For GRUB: edit /etc/default/grub and find the GRUB_CMDLINE_LINUX_DEFAULT line. Add the same flags:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt"
Then regenerate the config:
update-grub
The iommu=pt flag (passthrough mode) tells the kernel to only use IOMMU translation for devices you're actually passing through, leaving everything else running at full speed. Skipping it works but can cost you a bit of host performance across the board.
3. Load the VFIO kernel modules
Open /etc/modules and add these four lines if they're not already there:
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
On current kernels vfio_virqfd is built into the main vfio module and the line is harmless even if unused — leave it in, it won't cause an error.
4. Reboot and confirm IOMMU is active
reboot
After it comes back up, check the kernel log:
dmesg | grep -e DMAR -e IOMMU
You're looking for a line like DMAR: IOMMU enabled. If you see nothing at all, double-check the BIOS setting from step 1 — that's the most common reason this comes back empty.
5. Find your HBA's PCI address
lspci -nn | grep -iE "sas|sata|raid"
You'll get something like:
03:00.0 Serial Attached SCSI controller [0107]: Broadcom / LSI SAS2308 PCI-Express Fusion-MPT SAS-2 [1000:0087] (rev 05)
Two things matter here: the PCI address (03:00.0) and the vendor:device ID pair in brackets (1000:0087). You'll need both in the next steps.
6. Check the IOMMU group
Devices get grouped by the hardware, and everything in a group has to be passed through together. This quick script lists them all:
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
echo "Group ${d#*iommu_groups/}: $(lspci -nns ${d##*/})"
done | sort -t: -k1 -n
Ideally your HBA sits alone in its own group, or shares one with something harmless like a PCIe bridge. If it's grouped with your NVMe boot drive or your GPU, passthrough gets a lot messier, and you may need an ACS override patch — more on the tradeoffs of that in Best Practices below.
7. Bind the controller to vfio-pci
Create /etc/modprobe.d/vfio.conf:
options vfio-pci ids=1000:0087
Use the vendor:device ID from step 5, not the example above. If your host is currently using a driver like mpt3sas or ahci for this card, you also want to stop that driver from grabbing it first. Create /etc/modprobe.d/blacklist-hba.conf:
blacklist mpt3sas
Only blacklist this if the card isn't also driving disks the Proxmox host itself needs — which is exactly why the "don't passthrough your boot controller" rule from the prerequisites matters so much.
8. Rebuild initramfs and reboot
update-initramfs -u -k all
reboot
9. Confirm vfio-pci owns the device
lspci -k -s 03:00.0
The output should show Kernel driver in use: vfio-pci. If it still shows mpt3sas or another driver, the blacklist from step 7 didn't take — check the file for typos and rebuild initramfs again.
10. Add the device to your VM
In the Proxmox web interface, open the VM you want to pass the HBA into, go to Hardware, then Add > PCI Device. Choose Raw Device, pick your controller from the list, and check All Functions if the card exposes more than one PCI function. Leave Primary GPU off — this isn't a display device. Save, then start the VM.
Boot into TrueNAS or Unraid and check the storage view. You should see your physical drives listed by their real model numbers and serials, not as generic virtual disks.
Commands Explained
| Command | What it does |
|---|---|
proxmox-boot-tool status | Shows whether your host boots via GRUB or systemd-boot, so you know which file to edit for kernel parameters. |
update-grub | Regenerates the GRUB configuration after you change kernel boot parameters, so the new flags actually take effect on next boot. |
dmesg | grep -e DMAR -e IOMMU | Filters the kernel ring buffer for messages confirming IOMMU initialized correctly at boot. |
lspci -nn | Lists every PCI device with its vendor:device ID in brackets, which vfio-pci needs to claim a specific card. |
lspci -k -s <address> | Shows which kernel driver currently owns a specific PCI device — the way to confirm vfio-pci grabbed it instead of the native driver. |
update-initramfs -u -k all | Rebuilds the initial ramdisk for all installed kernels so the vfio-pci binding and blacklist rules apply at early boot, before other drivers load. |
Common Errors
A few things trip people up almost every time:
- The VM won't start, and the task log shows something like
vfio: error opening /dev/vfio/14: No such file or directory. This almost always means the vfio-pci binding didn't take — go back and checklspci -kfor the driver in use. - "Cannot allocate memory" or a similar failure at VM start. This usually shows up when the IOMMU group contains more devices than expected and one of them is still bound to a host driver. Recheck the group listing from step 6.
- The card shows up fine in TrueNAS, but individual disks are missing. Check physical cabling first — this is more often a loose SAS breakout cable than a Proxmox configuration problem.
- Proxmox itself won't boot after these changes. If you blacklisted a driver that the host actually needed for its own boot or storage, you'll land in an emergency shell. Boot from the Proxmox installer in rescue mode, remove the blacklist file, and rebuild initramfs from there.
Troubleshooting
Start with dmesg right after a failed VM start — search for the PCI address you're passing through, and you'll usually see exactly where things went wrong, whether that's a reset quirk, an IOMMU fault, or a driver conflict.
If the group check from step 6 shows your HBA sharing a group with unrelated hardware, that's usually a motherboard limitation rather than something you can configure your way out of. Some boards genuinely don't split PCIe lanes into separate IOMMU groups cleanly. Moving the card to a different physical PCIe slot sometimes fixes this, since slot wiring on the board affects grouping.
If you're stuck and considering an ACS override patch to force separate groups, know what you're trading away first — see the note in Best Practices. It's a real fix for a real problem, but it isn't free.
For SAS cards specifically, check whether the card is still in RAID mode instead of IT mode. A card in RAID mode will hide individual disks behind a virtual RAID volume even after passthrough works perfectly — TrueNAS will see one giant "disk" instead of your actual drives. Reflashing to IT mode with the manufacturer's tools fixes this, and it's a one-time job done before you even put the card in the passthrough pipeline.
Best Practices
Use a card that's actually meant to be an HBA, not a hardware RAID controller running in some compatibility mode. LSI/Broadcom cards flashed to IT mode (or bought that way secondhand) are the standard homelab choice for a reason — they're cheap, plentiful, and behave predictably under passthrough.
Keep the passthrough controller off your Proxmox boot drive, always. This is worth repeating because it's the single most common way people accidentally lock themselves out of their own host.
Write down the PCI address and vendor:device ID you used, somewhere outside the server. If you ever move the card to a different slot — during a hardware upgrade, say — the PCI address will change and the VM config will need updating to match.
On ACS override: some IOMMU groups can be split apart with a kernel patch that overrides how the platform reports device isolation (pcie_acs_override=downstream,multifunction as a boot parameter). It works, and a lot of homelab guides recommend it freely. I'd treat it as a last resort rather than a default. It weakens the isolation guarantees IOMMU groups exist to provide in the first place, which matters more if you're running anything security-sensitive alongside the passthrough VM on the same host.
Snapshot the VM's configuration (or just copy the .conf file from /etc/pve/qemu-server/) once passthrough is working. PCI passthrough config is one of the few things that doesn't always survive a VM restore cleanly if you're moving between different physical hosts later.
Frequently Asked Questions
Can I pass through my motherboard's onboard SATA controller instead of a separate HBA card?
Sometimes, but it's less reliable. Onboard SATA controllers are frequently grouped with other chipset devices — USB controllers, the CPU's root complex — in the same IOMMU group, which means you'd have to pass through more than you want, or none of it at all.
Does this remove the drives from Proxmox entirely?
Yes. Once the controller is bound to vfio-pci and passed to a VM, the Proxmox host has no visibility into those drives at all. They're not available as Proxmox storage, and they won't show up in the host's lsblk output.
Do I need enterprise server hardware for this to work?
No. Plenty of consumer desktop boards from the last several years support IOMMU just fine. What actually matters more is picking a board where your HBA lands in a clean IOMMU group, which varies more by motherboard chipset than by "consumer vs. enterprise" branding.
What's the difference between this and passing through a single disk?
Single-disk passthrough still routes through the host's own storage driver and typically loses SMART data and drive identity information along the way. Controller passthrough gives the guest direct hardware access, so SMART, serials, and drive behavior all come through exactly as they would on bare metal.
Will this work with Unraid the same way it does with TrueNAS?
Yes — the passthrough setup on the Proxmox side is identical regardless of which NAS operating system you're running in the guest. Unraid, like TrueNAS, wants direct disk access rather than virtual disks.
Conclusion
Passing through a whole HBA looks intimidating written out as a dozen steps, but in practice it's mostly one-time setup: BIOS flag, two bootloader lines, a couple of modprobe files, and a reboot or two to confirm each stage worked. Once it's done, adding or replacing drives is as simple as it would be on physical hardware — plug it in, and TrueNAS or Unraid just sees it.
If you take one thing away from this guide, make it the boot-drive warning: keep whatever controller your Proxmox host boots from completely separate from anything you're planning to pass through. Everything else here is recoverable with a bit of patience. That one mistake tends to mean a trip to the rescue console.