USB in WSL 2: How usbipd-win Attaches Devices over USB/IP
Why WSL cannot expose arbitrary USB devices directly, and how Windows binding, USB/IP transport, and Linux drivers fit together in usbipd-win.
Plugging a USB device into a Windows machine and expecting it to simply appear inside a WSL distribution the way it would on a native Linux install doesn’t work, and understanding why leads directly to the actual, supported solution: usbipd-win, a separate open-source project that Microsoft’s own documentation points to as the supported path for USB access in WSL.
Why WSL doesn’t expose USB devices natively
WSL 2 runs Linux inside a lightweight virtual machine, and unlike a directly-installed Linux system with immediate hardware access, that VM doesn’t automatically see the host’s USB devices — Windows itself retains ownership of physical USB hardware, exactly as it would for any other virtualized guest. USB passthrough isn’t something WSL’s core architecture provides out of the box; it requires an explicit bridging mechanism, which is precisely the gap usbipd-win fills.
What usbipd-win actually is
usbipd-win, maintained by developer Frans van Dorsselaer (GitHub handle dorssel), implements a USB/IP server for Windows — USB/IP being an existing open-source protocol and Linux kernel client capability for sharing USB devices over a network-style connection. Linux has long had USB/IP client support built in, but historically lacked a corresponding Windows-side server; usbipd-win specifically provides that missing server half, letting a Windows machine share a locally-connected USB device to a USB/IP client — which, for WSL’s purposes, is the Linux kernel running inside the WSL 2 VM.
The two-step attachment model
Getting a device from a Windows USB port into a WSL distribution is explicitly a two-step process, not implicit or automatic. First, binding: usbipd bind (requiring administrator privileges) marks a specific device as available for USB/IP sharing. This binding step is persistent — it survives reboots, and only needs to be performed once per device, though it does require that one-time administrative action. Second, attaching: usbipd attach --wsl, run afterward without requiring administrator rights, actually connects the previously-bound device to the running WSL environment over the USB/IP transport.
Windows loses access while a device is attached to WSL
A meaningful consequence of this model: while a USB device is attached to WSL, it is not simultaneously available to Windows itself. This isn’t a bug or a limitation to work around — it reflects the reality that the device is now being actively used by the Linux kernel inside WSL, and a device can’t be genuinely, safely used by two independent operating system kernels at the same time. Detaching it (or simply disconnecting the WSL side) returns it to normal Windows availability.
What gets installed, and why a firewall rule is part of it
Setting up usbipd-win installs a Windows service (displayed as “USBIP Device Host”), the usbipd command-line tool used for binding and attaching, and a firewall rule permitting local subnet connections to the service — necessary because USB/IP is, at its core, a network protocol, even when the “network” in question is entirely local, between the Windows host and the WSL 2 VM running on the same machine.
The Linux kernel still needs its own driver for the device class
Successfully attaching a device over USB/IP only gets its raw USB traffic into the WSL Linux environment — the Linux kernel running inside still needs the appropriate device-class driver for whatever the device actually is (a serial device, a specific microcontroller’s USB interface, a storage device) to actually make meaningful use of it. USB/IP transport and a working, functional device inside Linux are two separate concerns; confirming the expected kernel module is present and loaded (lsmod, dmesg after attaching) is a necessary step beyond just confirming the attach command itself succeeded.
Why this isn’t native passthrough, and why that distinction matters
It’s worth being precise about what this architecture actually is, since the terminology matters for setting correct expectations: this is a documented USB/IP bridge with real version and device-class limitations, not a low-level PCI or native USB passthrough mechanism giving WSL the same direct hardware access a bare-metal Linux install would have. Some device classes or specific USB features may not work correctly through this bridge even when basic connectivity succeeds, and troubleshooting an unusual device should account for this rather than assuming any USB device that works on bare-metal Linux will behave identically through usbipd-win.
Practical risks worth knowing before you rely on this for real work
A disconnect during an active operation — flashing firmware onto a microcontroller, writing to an attached storage device — carries the same risk any interrupted write operation does, and the USB/IP bridge doesn’t add extra protection against that risk. Keep usbipd-win and WSL themselves updated, since this is actively maintained software with real bug fixes landing over time, and avoid unplugging or detaching a device mid-operation on anything where an interrupted write could cause actual damage or data loss.
Verifying a device is genuinely working, not just attached
Confirming usbipd attach completed without error is not the same as confirming the device is functionally usable inside Linux. After attaching, checking lsusb (if installed) or dmesg for the device’s enumeration messages, and then actually exercising the specific functionality you need — reading from a serial port, mounting a storage device — is the only way to know the full chain from Windows binding through USB/IP transport to the Linux device driver is genuinely working end to end, rather than assuming success from the attach command’s exit code alone.
Listing currently bound and attached devices before troubleshooting further
usbipd list
Running this from an elevated Windows prompt shows every USB device’s current binding and attachment state at a glance — confirming whether a specific device is bound, attached, or neither is the fastest way to isolate which of the two steps actually failed, rather than guessing between a binding problem and an attachment problem when a device isn’t showing up as expected inside the distribution. Related: Running a Custom WSL 2 Kernel Without Losing the Supported Rollback Path · Fixing ‘Access Is Denied’ Errors in WSL After an Update
Sources: