Do Windows Runners Support Nested Virtualization?
No. WarpBuild Windows runners have no /dev/kvm. Nested virtualization is documented for cloud Linux x86-64 runners through a dynamic runs-on label.
No. Nested virtualization is documented for cloud Linux x86-64 runners through the nested-virtualization.enabled=true dynamic label, Windows runners are recorded as unsupported in the support matrix (nested virtualization documentation, checked on 2026-08-13), and that matrix is what to read before you design a workflow around /dev/kvm, because an unsupported label is accepted and ignored rather than rejected, so the job starts and the KVM-dependent step is what breaks.
Answer
The support matrix covers every runner class by platform and by hosted or BYOC placement. Every row below comes from the nested virtualization documentation, checked on 2026-08-13.
| Runner class | Nested virtualization | How it is turned on |
|---|---|---|
| Cloud: Linux x86-64 | Yes | nested-virtualization.enabled=true appended to the runs-on label |
| Cloud: Linux ARM64 | No | Not available |
| Cloud: Windows | No | Not available |
| Cloud: macOS | No | Not available |
| BYOC on AWS: Linux x86-64 | Yes | Automatic when every instance type in the runner set supports it |
| BYOC on GCP: Linux x86-64 | Yes | Automatic when every instance type in the runner set supports it |
| BYOC on Azure: Linux x86-64 | Yes | Automatic on supported VM sizes |
| BYOC: ARM64 runner sets | No | Not available |
| BYOC: Windows runner sets | No | Not available |
Two rows carry the practical answer for a Windows pipeline. Cloud Windows runners have no /dev/kvm, and BYOC Windows runner sets do not change that, so a KVM-dependent step has to run on a Linux x86-64 machine wherever the rest of the workflow lives.
The expectation usually comes from GitHub's own changelog, which announced hardware-accelerated Android virtualization on GitHub-hosted Windows and Linux larger runners (GitHub changelog, February 23, 2023). WarpBuild exposes that capability on the Linux x86-64 line.
Here is the Linux job that needs /dev/kvm. The dynamic label goes after a semicolon on the same runs-on value, and the permissions step runs before the emulator action:
name: instrumentation-tests
on:
pull_request:
jobs:
android-tests:
runs-on: warp-ubuntu-latest-x64-8x;nested-virtualization.enabled=true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
arch: x86_64
script: ./gradlew connectedDebugAndroidTestThe permissions step is required on GitHub-hosted runners too, because the default device permissions on /dev/kvm are crw-rw---- root:kvm and the runner user is outside that group (nested virtualization documentation). Skip it and reactivecircus/android-emulator-runner logs ProbeKVM: This user doesn't have permissions to use KVM (/dev/kvm)., then launches with -accel off and runs the suite in software emulation.
Detail
When the workload cannot move to Linux
Split the workflow by what each step actually needs. WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners, so the Windows compile and the KVM leg sit in one workflow file under one account.
A .NET service with an Android client is the common shape: the server build and unit tests stay on a warp-windows- label, and the instrumentation suite moves to a Linux x86-64 job with the dynamic label. Artifacts travel between the two jobs through actions/upload-artifact and actions/download-artifact, and needs: orders them.
Two Windows workloads look like nested virtualization and are something else. Hyper-V isolation for Windows containers does need it, and the fix is matching the base image tag to the host release rather than isolating the container (Microsoft container version compatibility reference, checked on 2026-08-13). WSL2 also needs it, so a build script that shells into WSL belongs on a Linux runner directly.
Where the workload genuinely cannot leave Windows, such as a driver test that needs a Windows guest, no runner class in the catalog provides it and the test stays on hardware you operate.
What the split costs
Take a repository that merges 500 pull requests a month, with a 10 minute Windows build and test leg and a 12 minute Android instrumentation leg. Rates come from the cloud runners documentation, checked on 2026-08-13.
- Windows leg on
warp-windows-latest-x64-8xat $0.032 per minute: 500 x 10 x $0.032 = $160.00 per month. - Instrumentation leg on
warp-ubuntu-latest-x64-8xat $0.016 per minute: 500 x 12 x $0.016 = $96.00 per month. - Total: $256.00 per month, with the two legs running in parallel so wall clock is set by the longer one.
Per-minute rates for every label are on the pricing page.
When the emulator leg fails and the logs do not explain why, the Action Debugger opens a shell on the runner while the job is held, which is where ls -l /dev/kvm settles whether the device is present.
Related Questions
Can I run Android emulator tests on a Windows GitHub Actions runner?
No. Send that job to a Linux x86-64 label with nested-virtualization.enabled=true and the KVM permissions step, as shown above. The runners that expose /dev/kvm page lists the sizes available for it.
What happens if I add nested-virtualization.enabled=true to a Windows label?
The label is silently ignored and the job runs normally without nested virtualization (nested virtualization documentation). No error is raised at queue time, so treat a passing job as no evidence that KVM was present.
Do BYOC Windows runner sets get nested virtualization?
No. On BYOC it is automatic on Linux x86-64 runner sets on AWS, GCP, and Azure when every selected instance type supports it, and a mixed instance list disables it to keep behavior consistent across jobs. Windows runner sets stay outside that support.
Can I use Hyper-V isolation for Windows containers on a WarpBuild Windows runner?
No. Match the base image tag to the host release instead: ltsc2022 images on the warp-windows-latest-x64 labels and ltsc2025 images on the warp-windows-2025-x64 labels. The full label list with sizes and rates is on the Windows runner page.
Check the platform rows on the Windows runner page, read the term itself in the nested virtualization glossary entry, and price the Linux side of the split against your own job minutes on the pricing page.
Start with $10 in free credits
Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.