The infamous error 43 is triggered by the Nvidia Windows driver, in case it recognizes the GPU is used inside a virtual machine with GPU passthrough. This means the driver won’t load correctly during the system startup leaving you with cumbersome 800 by 600 display resolution.
An examination of the Windows Device Manager will unveil the culprit – Code 43
Windows has stopped this device because it has reported problems. (Code 43)

Luckily, KVM/QEMU is able to hide the fact that the Nvidia driver is running a virtual environment.
The tested system setup
This method has been tested for the following versions
Host:
- OS: Ubuntu 18.04, as well as a 16.04
- Kernel: 4.15 – 5.3.6
- Hypervisor: QEMU 2.12.0 up to 4.1
- Libvirt: version 4.6.0 up to 4.7.0
One can use virsh version
in order to display the current version status.
Guest:
- OS: Windows 10 1803 – 1903
- VM chipset: i440FX, Q35
- Nvidia driver: 399.07 – 441.12
- GPU: Geforce GTX 970 and Geforce GTX 1060
Fixing error 43
In order to hide that the system is running on a hypervisor, KVM supports the “hidden” flag.
Depending on whether you call QEMU directly or call it via Libvirt the flag syntax differs.
Set KVM hidden via Libvirt xml
In order edit the virtual machines configuration use:
virsh edit your-windows-vm-name
Once your done editing, you can use CTRL+x CTRL+y
to save the changes.
For QEMU 3.0 and later the required flags are “vendor_id
” in the hyperv section, and “hidden
” in the kvm section, of the features block, of the virtual machines xml definiton. I think it is recommended to use a 12 character value (see excerpt marked green).
Additionally, in case you are using QEMU 4.0 (or higher) in combination with a Q35 chip, the flag ‘ioapic driver='kvm'
‘ needs to be added in the features section (see excerpt marked blue).
Excerpt from libvirt xml file
...
<features>
<acpi/>
<apic/>
<hyperv>
<relaxed state='on'/>
<vapic state='on'/>
<spinlocks state='on' retries='8191'/>
<vendor_id state='on' value='1234567890ab'/>
</hyperv>
<kvm>
<hidden state='on'/>
</kvm>
<vmport state='off'/>
<ioapic driver='kvm'/>
</features>
...
Set KVM hidden for direct QEMU usage
In case you call QEMU directly you have to add the flags ‘kvm=off
‘ and ‘vendor_id=null
‘ on your cpu argument (see excerpt marked green).
Additionally, in case you are using QEMU 4.0 (or higher) in combination with a Q35 chip, use the machine argument ‘kernel_irqchip=on
‘.
Example for virtual machine with host-passthrough set as CPU model and Q35 as machine type:
...
-cpu 'host,kvm=off,hv_vendor_id=null' \
-machine 'type=q35,kernel_irqchip=on' \
...
Using QEMU command arguments in the libvirt XML definition
Just for the sake of completeness (and historical compatibility of this article), there is a third way of enabling the hypervisor spoofing. Actually it is a combination of the two described earlier, as it is possible to add QEMU arguments to the libvirt xml defintion file.
These arguments are called after the definition has been parsed, and usually overwrite the settings made via XML structure. Thus it is not recommended to use both ways for one setting in the same definition file.
First of all find the very first line, which should read:
<domain type='kvm'>
and replace it with:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
Find the line which ends with </devices>
and add the following block afterwards (or alter the block if it already exists):
...
</devices>
<qemu:commandline><qemu:arg value='-cpu'/>
<qemu:arg value='host,kvm=off,hv_vendor_id=null'/>
<qemu:arg value='-machine'/>
<qemu:arg value='q35,kernel_irqchip=on'/></qemu:commandline>
</domain>
Attention: Make sure <devices>
and <qemu:commandline>
have the same indent.
Thats it – these settings work for me.
Sources
As usual, the glorious arch wiki has further information and help; i.e. it recommends using a 12-character alphanumeric string as vendor ID.
Post updates
21.09.2019 – added further information regarding qemu 4.0 and error 43
07.11.2019 – updated the article structure
This got me past code 43, but now I get no video during Windows 10 boot. I can get into safe mode no issue, but normal boot produces no video signal and the monitor goes to sleep.
How do i fix Code 43 in Xen, as KVM my USB 3 card is grabed by XHCI_HCD!!!!!!!! and i don’t have much success recompiling Kernel to make it a damm module.
Unfortunately, I don’t have much experience with Xen. Which USB-3 card are you using? I found this thread. Also see the redhat post they are referencing.