How to Migrate a VM Between Two Unraid Servers
Moving a virtual machine from one Unraid box to another isn’t as scary as it sounds. Under the hood, Unraid VMs are just standard KVM/QEMU domains, so the process boils down to: copy the disk, copy the config, fix a couple of host-specific details, and boot it up. Here’s the full walkthrough, based on a real migration I ran recently between two of my own servers (referred to below as Old_Server and New_Server).
Before You Start
A few things to have ready:
- Both servers reachable on the same network
- SSH access to both (via the Unraid terminal or a direct SSH session)
- Enough free space on the destination for the VM’s disk image
- The VM shut down on the source server — never copy a running VM’s disk
Step 1: Find the VM’s Disk Image
Unraid usually stores VM disks under /mnt/user/domains/<vm-name>/, but yours might live somewhere custom (a different share, a pool, or unassigned devices). If you’re not sure, pull it straight from the VM’s XML definition:
virsh dumpxml <vm-name> | grep -A2 "<disk"
This shows the <source file='...'/> path for each attached disk — note the real path before assuming the default location.
Step 2: Check the Disk Size
du -sh /path/to/vdisk1.img
This tells you how long the copy will take and whether it’s worth running in the background.
Step 3: Copy the Disk to the New Server
mkdir -p /path/on/New_Server/domains/<vm-name>/
nohup rsync -avP --progress /path/to/vdisk1.img root@New_Server:/path/on/New_Server/domains/<vm-name>/ > /root/vmcopy.log 2>&1 &
Running it with nohup and backgrounding it (&) keeps the transfer alive even if your SSH session drops. Watch progress with:
tail -f /root/vmcopy.log
A word of caution: if SSH between the two servers isn’t already using key-based auth, a backgrounded rsync can hang silently waiting on a password prompt that never arrives. If nothing shows up in the log after a minute or two, check for stuck processes:
ps aux | grep rsync
If you see rsync/ssh processes sitting idle, kill them and set up an SSH key first:
ssh-keygen -t ed25519 -N "" -f /root/.ssh/id_ed25519
cat /root/.ssh/id_ed25519.pub | ssh root@New_Server "mkdir -p /root/.ssh && cat >> /root/.ssh/authorized_keys && chmod 700 /root/.ssh && chmod 600 /root/.ssh/authorized_keys"
Then retry the copy — it should run unattended from here on.
(Note: Unraid’s default root filesystem is read-only on part of /root, so you may see a harmless known_hosts write warning during SSH connections. It doesn’t block anything — the connection still succeeds.)
Step 4: Export the VM’s XML Configuration
Once the disk copy is running (or finished), grab the VM’s full definition from the source server:
virsh dumpxml <vm-name> > /root/vm-export.xml
Take a look through it for a few things that will need adjusting for the new host:
- Disk path — update if the destination path differs from the source
- Attached ISOs (cdrom entries) — these almost certainly won’t exist on the new server; safe to remove if the OS is already installed
- CPU pinning (
<cputune>) — if the two servers have different CPU models or core counts, pinned core IDs from the old server won’t map correctly to the new one’s topology. Easiest fix is to delete the entire<cputune>block and let the new host’s scheduler handle placement - Network bridge name — confirm the new server uses the same bridge name (commonly
br0); check withip a | grep br0on the destination
Step 5: Handle the UEFI NVRAM File (If Applicable)
If your VM uses UEFI/OVMF firmware, it has a small NVRAM file tied to its UUID, stored at:
/etc/libvirt/qemu/nvram/<uuid>_VARS-pure-efi.fd
Copy this over too, to preserve the exact UEFI state:
scp /etc/libvirt/qemu/nvram/<uuid>_VARS-pure-efi.fd root@New_Server:/root/
On the new server:
mkdir -p /etc/libvirt/qemu/nvram/
mv /root/<uuid>_VARS-pure-efi.fd /etc/libvirt/qemu/nvram/
If you skip this, libvirt will just generate a fresh NVRAM file — the VM will still boot, but any custom UEFI boot order or settings will reset to firmware defaults.
Step 6: Verify the Firmware File Exists
Before starting the VM, confirm the OVMF loader file referenced in the XML actually exists on the new server:
ls -la /usr/share/qemu/ovmf-x64/OVMF_CODE-pure-efi.fd
Both servers running the same Unraid version should already have this in place.
Step 7: Define and Start the VM
Copy your edited XML to the new server, then define the VM:
virsh define /root/vm-export.xml
virsh list --all
You should see the VM listed as shut off. Start it:
virsh start <vm-name>
virsh list --all
It should now show as running.
Step 8: Verify Everything Actually Works
Give the guest OS a minute to boot, then confirm network connectivity:
ping -c 4 <vm-ip>
If that responds, SSH in and check that whatever services the VM runs actually came back up cleanly. If a service normally runs under systemd, check it there; if not, a simple process check works just as well:
ps aux | grep <process-name>
Step 9: Clean Up (Whenever You’re Ready)
Once you’re confident the VM is stable on its new home — I’d recommend giving it at least a day of normal use first — you can remove the old copy from the source server:
virsh undefine <vm-name> --nvram
rm -rf /path/to/old/domains/<vm-name>/
There’s no rush on this step. Keeping the old copy around costs disk space, but it’s a free safety net until you’re sure the migration is solid.
Summary
Migrating a VM between Unraid servers is really just a disk copy plus an XML config with a few host-specific edits. The main gotchas are CPU pinning that doesn’t map across different hardware, SSH auth that isn’t set up yet, and remembering the NVRAM file if your VM uses UEFI. Once you’ve done it once, it’s a pretty quick process the next time around.
