Last checked: 27 October 2026.

When Windows 10 or 11 lists a board as “USB Serial Device (COMx)”, it has bound Microsoft’s own usbser.sys. It does that for any device that reports USB class 02h (CDC) with subclass 02h (ACM), and it never needs a download. Boards built on a vendor-specific bridge chip (CH340, CP2102, FT232R, PL2303) don’t report that class. Without the vendor’s driver they sit under “Other devices” with Code 28, and no amount of waiting for usbser fixes that.

⬇ Nothing to download for CDC boards

Windows 10 / 11 · driver: usbser.sys, loaded by %Systemroot%\INF\usbser.inf · matched by compatible ID USB\Class_02&SubClass_02 or USB\Class_02

Microsoft: USB serial driver (Usbser.sys)

Board with a bridge chip instead? Get the vendor driver from our mirrors: CH340/CH341 · CP2102/CP210x · FTDI FT232 · PL2303

usbser.sys ships inside Windows, so there’s no file for us to host and no checksum to compare. If someone offers you a “USB Serial Device driver” download, you don’t need it.

Which boards get usbser.sys, and which need a driver

The class codes below come from the firmware source of each board, not from forum lore. The vendor-chip rows are confirmed by Linux, which binds those chips by VID:PID in dedicated drivers (ch341.c, cp210x.c, ftdi_sio, pl2303.c) and never by the CDC class.

Board / chip VID:PID What the firmware reports Windows 10/11 with no download Source
Arduino Leonardo / Micro (ATmega32U4) 2341:8036 / 8037 Device EFh/02h/01h (IAD), interface 02h/02h, protocol 00h usbser, “USB Serial Device” ArduinoCore-avr USBCore.cpp, CDC.cpp, boards.txt
Arduino Zero, MKR WiFi 1010, Nano 33 IoT (SAMD21) 2341:804D / 8054 / 8057 Same as above usbser ArduinoCore-samd USBCore.cpp, CDC.cpp
Raspberry Pi Pico (SDK stdio_usb) 2E8A:000A EFh/02h/01h; CDC interface named “Board CDC”, plus a vendor “Reset” interface with a Microsoft OS 2.0 descriptor usbser for the COM port; WinUSB for “Reset” pico-sdk stdio_usb_descriptors.c
Anything on TinyUSB’s CDC macro (CircuitPython, many RP2040/ESP32-S2 builds) varies Interface 02h/02h, protocol 00h (“no specific protocol”) usbser TinyUSB usbd.h TUD_CDC_DESCRIPTOR
STM32 CubeMX CDC example 0483:5740 Device 02h/02h/00h, interface 02h/02h/01h (AT commands) usbser STM32CubeF4 CDC_Standalone usbd_desc.c, usbd_cdc.c
ESP32-S3 / C3 built-in USB 303A:1001 CDC-ACM serial + a JTAG interface usbser for serial; JTAG needs Espressif’s driver ESP-IDF docs
Black Magic Probe 1D50:6018 Two CDC ports + DFU (FEh/01h/01h) + trace (FFh); current firmware adds Microsoft OS descriptors for the last two usbser for both COM ports blackmagic usb_descriptors.h
WCH CH343 / CH9102 1A86:55D3 / 55D4 CDC usbser works; WCH driver optional our CH9102 guide
WCH CH340 / CH341 1A86:7523 / 5523 Vendor-specific Code 28, “USB2.0-Serial” Linux ch341.c
Silicon Labs CP2102 10C4:EA60 Vendor-specific Code 28, “CP2102 USB to UART Bridge Controller” Linux cp210x.c
FTDI FT232R / FT231X 0403:6001 / 6015 Vendor-specific Code 28, “FT232R USB UART”, until the FTDI driver is in Linux ftdi_sio_ids.h
Prolific PL2303 067B:2303 Vendor-specific Code 28 until the Prolific driver is in Linux pl2303.h

One detail the table settles: the protocol byte doesn’t matter. Arduino and TinyUSB send protocol 00h, ST’s example sends 01h, and all of them get usbser. That’s because Microsoft lists the match as USB\Class_02&SubClass_02 or plain USB\Class_02, with no protocol part. The second form covers the STM32 case, where the class sits in the device descriptor itself. Per Microsoft’s Standard USB identifiers, that turns into the compatible ID USB\Class_02 for the whole device.

The CH340 and CP2102 names in the last rows are worth knowing because people paste them straight into a search engine. “cp2102 usb to uart bridge controller” and “ft232r usb uart driver” are among the queries that bring readers to this site from Bing.

Diagram: Windows checks for a vendor INF hardware ID match, then CDC class 02 for usbser.sys, then a Microsoft OS descriptor for WinUSB; with no match the device lands in Other devices with Code 28
The order Windows 10/11 follows for each device or interface. A vendor INF that lists the hardware ID wins over the class match. Diagram: TechBenchLab, from Microsoft Learn.

Check yours in 30 seconds

  1. Device Manager → the device → Properties → Details → Compatible Ids. If you see USB\Class_02&SubClass_02, usbser should take it. If you only see USB\Class_FF or nothing beyond the VID:PID, you need the vendor driver.
  2. Or, on Windows 11 21H2 or newer, list every Code 28 device along with its IDs in one go: pnputil /enum-devices /problem 28 /deviceids. The /problem filter works from Windows 10 1903, and /deviceids needs 21H2 (PnPUtil syntax).
  3. To see which INF a working port uses: pnputil /enum-devices /class Ports /drivers. usbser.inf means in-box, and oemNN.inf means a vendor driver took over.

Common problems

FAQ

Do I need the Arduino or STM32 “VCP driver” on Windows 11? Not for the boards in the green rows above. Install a vendor driver only if Compatible Ids show no class 02.

The port is there, but uploads fail with “Access is denied”. That isn’t a driver problem. Another program holds the port; see COM port busy.

Related guides

Sources