Home / Guides / Troubleshooting / Windows

CUDA works on Windows but not inside WSL2

WindowsLinux

Written by Jakub Rusinowski · Last updated September 1, 2026

AI educator & workshop leader on local LLM deployment

The error

NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.

/sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link

>>> torch.cuda.is_available()
False

Which one is it?

If you seeThe cause isGo to
You ran apt install nvidia-driver-* or a .run installer inside WSLThe Linux driver overwrote the libcuda stub the Windows driver projects into WSLFix 1: remove the Linux driver from the distro
nvidia-smi is "command not found" inside WSLThe projected driver directory is not on your PATHFix 2: call it at /usr/lib/wsl/lib/nvidia-smi
It worked, then stopped after a Windows update or sleepThe WSL VM is holding a stale projection of the host driverFix 3: wsl --shutdown and relaunch
The ldconfig.real ... is not a symbolic link warning on every apt runThe read-only WSL projection cannot hold real symlinks; most loaders ignore it, some do notFix 5: rebuild the symlinks in a writable directory
wsl cat /proc/version shows a kernel older than 5.10.16.3The WSL kernel predates usable GPU paravirtualisationFix 4: wsl.exe --update

When you see it

The card is fine and Windows can see it. nvidia-smi in PowerShell prints a normal table, games run, and torch.cuda.is_available() is True in a Windows Python. Cross into your Ubuntu distro and the same GPU has vanished.

What's actually going on

WSL2 does not have its own GPU driver and is not supposed to. The NVIDIA driver you install on Windows is projected into the Linux VM at /usr/lib/wsl/lib, where it appears as libcuda.so and friends — a stub backed by the host driver. NVIDIA's guidance on this is unusually blunt: the Windows driver is the only driver you need, and you must not install any NVIDIA GPU Linux driver inside WSL 2. Installing one overwrites that projected stub with a Linux driver that has no hardware to talk to, and GPU access stays broken until you remove it. This is the cause of the overwhelming majority of "CUDA works on Windows, not in WSL" reports, and it is why the fix is subtractive rather than additive.

How to fix it

1. Remove any NVIDIA Linux driver you installed inside the distro

Do this first, before installing anything else. If dpkg -l | grep nvidia lists driver packages — nvidia-driver-*, libnvidia-*, nvidia-dkms-* — inside WSL, they are the problem. Purging them lets the host projection take over again on the next restart. A .run installer needs its own uninstaller (sudo /usr/bin/nvidia-uninstall) instead.

⚠️ This removes packages from the WSL distro only. It does not touch your Windows driver, your GPU, or anything outside WSL — but read the list apt prints before you confirm it.

bash
# bash, inside WSL — see what is installed
dpkg -l | grep -i nvidia

# Purge Linux driver packages (NOT the CUDA toolkit)
sudo apt-get purge -y "nvidia-driver-*" "libnvidia-*" "nvidia-dkms-*"
sudo apt-get autoremove -y
Did it work? Run wsl --shutdown in PowerShell, reopen the distro, and check the projection is intact. The library should be present under /usr/lib/wsl/lib.
ls -l /usr/lib/wsl/lib/libcuda.so*
/usr/lib/wsl/lib/nvidia-smi

2. Install only the WSL-Ubuntu CUDA toolkit variant

The CUDA toolkit and the display driver are separate things, and inside WSL you want the toolkit without the driver. NVIDIA publishes a WSL-Ubuntu package variant that deliberately excludes it. Choose that one from the CUDA downloads page, and do not select the cuda, cuda-13-x or cuda-drivers meta-packages — those pull the Linux driver back in and put you straight back where you started. If nvidia-smi is not on your PATH after this, it lives at /usr/lib/wsl/lib/nvidia-smi.

bash
# bash, inside WSL — install the toolkit ONLY, never the driver meta-packages
sudo apt-get install -y cuda-toolkit-13-0

# NOT these:
#   sudo apt-get install cuda
#   sudo apt-get install cuda-drivers
Did it work? The compiler reports a version and the runtime sees the device. If nvcc works but nvidia-smi does not, you still have a driver problem, not a toolkit problem.
nvcc --version
/usr/lib/wsl/lib/nvidia-smi
python3 -c "import torch; print(torch.cuda.is_available())"

3. Restart the whole WSL VM before you debug anything else

wsl --shutdown is the cheapest fix on this page and it resolves a real class of failure: the WSL VM holds its projection of the host driver from when it started, so a Windows driver update installed under a running distro leaves the VM with a stale one. Closing the terminal window does not do this — the VM keeps running in the background for several seconds after and often longer.

PowerShell
# PowerShell, on the Windows side
wsl --shutdown
wsl --status

# then reopen your distro
Did it work? Inside the freshly started distro, nvidia-smi should print the same GPU and driver version you see in PowerShell.
nvidia-smi --query-gpu=name,driver_version --format=csv

4. Check the platform floor — Windows build, WSL kernel, and GPU generation

GPU passthrough needs Windows 11 or Windows 10 build 19043 or newer, and a WSL kernel of at least 4.19.121 — 5.10.16.3 or newer is what you actually want. Maxwell-generation cards are not supported under WSL, and Pascal or newer is the practical requirement, which is a stricter bar than native Windows. wsl.exe --update pulls the current kernel.

PowerShell
# PowerShell
winver                 # Windows version and build
wsl.exe --update
wsl cat /proc/version  # the WSL kernel version

5. Fix the libcuda symlink warning without editing the read-only projection

/usr/lib/wsl/lib is a read-only projection of the Windows driver, so the is not a symbolic link warning cannot be fixed in place — and trying is how people break a working setup. The safe form is to copy the libraries somewhere writable, recreate the symlinks there, and put that directory ahead of the WSL path in the loader config. Note that this is cosmetic for most workloads: the warning is harmless unless a loader you use actually follows the symlink.

⚠️ A wsl --shutdown resets the projection at /usr/lib/wsl/lib, not your copy — so after a Windows driver update your copied libraries are stale and must be recreated, or you will be running against an old libcuda.

bash
# bash, inside WSL
sudo mkdir -p /usr/lib/wsl/drivers-copy
sudo cp /usr/lib/wsl/lib/libcuda.so.1.1 /usr/lib/wsl/drivers-copy/
sudo ln -sf /usr/lib/wsl/drivers-copy/libcuda.so.1.1 /usr/lib/wsl/drivers-copy/libcuda.so.1
sudo ln -sf /usr/lib/wsl/drivers-copy/libcuda.so.1   /usr/lib/wsl/drivers-copy/libcuda.so
echo "/usr/lib/wsl/drivers-copy" | sudo tee /etc/ld.so.conf.d/000-wsl-cuda.conf
sudo ldconfig
Did it work? The warning should be gone from the next sudo ldconfig run, and the loader should resolve libcuda to your copy.
sudo ldconfig 2>&1 | grep -i libcuda || echo "no libcuda warnings"
ldconfig -p | grep libcuda

6. Consider whether you need WSL at all Most common fix

Worth saying plainly, because a lot of guides imply otherwise: for a single-GPU machine running Ollama or LM Studio, native Windows is simpler and about as fast. WSL earns its keep when you need a Linux toolchain — vLLM, a CUDA build, a Python stack that fights you on Windows. It costs you Unified Memory, which is not available under WSL, and pinned system memory, which is limited there. If you came to WSL only because a tutorial used bash, running natively removes this entire page from your life. Size the model to your card and you are done.

Check what fits your hardware — check which models fit your card before you spend an evening on driver plumbing
Open the VRAM checker →

If none of this worked

If nvidia-smi works inside WSL and your workload still cannot see the GPU, the problem has moved downstream to the container runtime or the framework. Docker Desktop with the WSL2 backend rides on exactly this plumbing, so fixing WSL fixes Docker — but the container also needs the NVIDIA Container Toolkit.

Include this when you report it

Also affects: Linux

Related

A model that fits most setups:
View model & requirements →

Frequently asked questions

Do I need to install an NVIDIA driver inside WSL?

No, and doing so breaks GPU access. NVIDIA states the Windows display driver is the only driver required, and that no Linux GPU driver should be installed inside WSL 2. The Windows driver is projected into the distro at /usr/lib/wsl/lib as a libcuda stub.

Why is nvidia-smi missing inside WSL when the GPU works?

It is present but not always on your PATH. It ships as part of the projected driver at /usr/lib/wsl/lib/nvidia-smi. Call it by full path to confirm the GPU is visible, then add that directory to PATH if you want the bare command to work.

Is the "libcuda.so.1 is not a symbolic link" warning serious?

Usually not. It comes from ldconfig objecting to the read-only WSL projection and most workloads run fine alongside it. It matters only when a loader you depend on follows the link. The fix is to recreate the symlinks in a writable directory, never to edit the projection.

Does WSL2 support every GPU that Windows does?

No. Maxwell-generation cards are not supported under WSL, so Pascal or newer is the practical floor — stricter than native Windows, where Ollama supports compute capability 5.0 and above. Unified Memory is also unavailable under WSL and pinned system memory is limited.

Should I run Ollama in WSL or natively on Windows?

Natively, for most single-GPU setups: it is simpler, roughly as fast, and avoids this whole class of problem. Choose WSL when you need a Linux toolchain that Windows makes painful — a CUDA build, vLLM, or a Python stack that only ships Linux wheels.