Electronics Design AU
USB

Why Is My USB Device Failing Enumeration?

Last updated 2 July 2026 · 7 min read

Direct Answer

USB enumeration failure — a device showing as 'Unknown USB Device', failing descriptor requests, or not appearing at all — almost always traces back to one of five causes: an invalid or malformed device/configuration descriptor, a VID/PID that conflicts with an installed driver, an inaccurate USB clock (Full Speed requires 48 MHz within ±0.25%), incorrect D+ pull-up timing, or drawing more than 100 mA before the host finishes configuring the device. A USB protocol analyser that captures the actual enumeration sequence is the fastest way to identify which of these is the root cause, rather than guessing from host-side symptoms alone.

Detailed Explanation

USB enumeration is the sequence a host runs every time a device is connected: reset the bus, read the first 8 bytes of the device descriptor to learn the maximum packet size for endpoint 0, reset again, assign a unique bus address, read the full device and configuration descriptors, and finally issue SET_CONFIGURATION to activate the device's chosen configuration. A failure at any step produces a different symptom, and matching the symptom to the step is the fastest way to find the root cause. For the full descriptor hierarchy and enumeration overview, see What Is USB?.

Reading the symptom back to the failing step

  • Device is not detected at all (no port activity, no driver prompt) — the device isn't presenting on the bus. This points to hardware: no D+ pull-up, dead USB clock, or a power/VBUS problem preventing the USB peripheral from initialising.
  • "Unknown USB Device (Device Descriptor Request Failed)" on Windows, or a bus reset loop on Linux (dmesg showing repeated device descriptor read/64, error -71) — the host got as far as issuing the first GET_DESCRIPTOR request but never received a valid response. This is almost always a clock accuracy or pull-up timing fault, not a firmware logic bug.
  • Device is detected, address is assigned, but no driver loads — the low-level protocol succeeded; the fault is in the descriptor content (VID/PID, class/subclass/protocol fields) rather than the signalling.
  • Device enumerates then disconnects/reconnects repeatedly — usually a power draw or brown-out issue: the device resets mid-enumeration because a regulator sags under load, or an inrush current trips the host's overcurrent protection.

Descriptor and firmware-level causes

Malformed or inconsistent descriptors. The device descriptor's bMaxPacketSize0 for endpoint 0 must match what the device actually returns on the wire — a mismatch between the value in the descriptor and the peripheral's configured endpoint 0 packet size causes the host to read garbage or time out after the initial 8-byte read. Configuration descriptor length fields (wTotalLength) must exactly match the sum of all sub-descriptors that follow; an off-by-one error here is a common cause of the host truncating or misparsing the descriptor set.

VID/PID conflicts. The Vendor ID must be one actually assigned to your organisation by the USB Implementers Forum (or a vendor-provided development VID/PID for prototyping, per that vendor's terms). Reusing a VID/PID that's already registered to a different device class on the host — for example, reusing an FTDI VID/PID on a device that isn't a real FTDI chip — can cause Windows to bind the wrong class driver or refuse to install one, producing a "device not recognised" symptom even though enumeration itself completed.

Interface and endpoint descriptor errors. Endpoint addresses must be unique per direction (IN/OUT) within an interface, and wMaxPacketSize for each endpoint must not exceed what the USB peripheral hardware supports at the negotiated speed (64 bytes max for Full Speed control and bulk endpoints, for example). Declaring an endpoint the hardware can't actually service causes silent failures that only show up in the protocol trace, not in host-side error messages.

Clock and signalling-layer causes

USB Full Speed (12 Mbit/s) requires the device's bit clock to be accurate to within ±0.25% of 48 MHz — tight enough that most MCUs cannot meet it from an internal RC oscillator and require a PLL locked to an external crystal. If the USB clock tree is misconfigured (wrong PLL multiplier, crystal not started, clock source silently falling back to an inaccurate internal oscillator), the device's bit timing drifts outside the host's receive window. The result is exactly the "Device Descriptor Request Failed" symptom above: the host sees bus activity (the pull-up is detected) but can't decode a valid response.

D+ pull-up timing matters independently of clock accuracy. A Full Speed device signals its presence by pulling D+ high through a 1.5 kΩ resistor — on most modern MCUs this is an internal, software-enabled pull-up. Enabling it too early (before the USB peripheral clock and stack are actually initialised) causes the host to begin enumeration before the device can respond, producing a bus reset race that can leave the device unresponsive until re-plugged. The pull-up should be enabled only once the USB stack is fully initialised and ready to service control transfers.

Power-related causes

A device must not draw more than 100 mA (USB 2.0) from VBUS before the host issues SET_CONFIGURATION — drawing more trips the host port's current limiter, which power-cycles or disables the port. This is easy to violate unintentionally: a large VBUS decoupling capacitor charging on connection, or peripheral ICs powered directly from VBUS and enabled before the USB stack negotiates configuration, can both exceed the unconfigured current budget. See USB-C PCB design for VBUS decoupling and inrush considerations at the hardware level.

Diagnosing with a protocol analyser

Host-side error messages ("Unknown USB Device", code 43, driver install failure) describe the symptom the OS observed, not the cause. A USB protocol analyser (hardware analysers like Total Phase Beagle, or software capture via Wireshark with USBPcap on Windows or usbmon on Linux) captures the actual bus traffic — the exact point where the device stops responding, whether descriptor content was malformed, or whether the device reset unexpectedly — and turns a guessing exercise into a direct read of what failed. For firmware-side USB stack debugging (breakpoints inside the enumeration state machine), see how to debug embedded firmware.

Design Considerations

  • Verify the USB clock source explicitly in firmware, not just in the clock configuration tool output — confirm the actual running frequency with an oscilloscope or the MCU's clock recovery/frequency measurement peripheral if available, rather than trusting the configuration was applied correctly.
  • Enable the D+ pull-up as the last step of USB stack initialisation, after all endpoint 0 handling is ready to service control transfers, not as an early GPIO setup step.
  • Budget unconfigured current draw separately from configured current draw — audit every peripheral IC and capacitor on VBUS for its behaviour in the first few hundred milliseconds after connection, not just its steady-state configured current.
  • Use vendor-provided development VID/PID allocations correctly — check the terms of use (typically non-commercial/prototyping only) and plan to obtain a proper VID before production if the product will ship.
  • Capture a protocol trace before changing firmware speculatively. Guessing at descriptor or clock fixes without a trace showing where enumeration actually stops wastes debugging cycles on the wrong layer.

Common Mistakes

  • Assuming a driver problem when the fault is in the signalling layer. "Unknown USB Device" with a descriptor request failure is a Full Speed clock or pull-up timing fault, not a Windows driver issue — reinstalling drivers will not fix it.
  • Enabling the D+ pull-up before the USB peripheral clock is confirmed running. This creates a race where the host starts enumerating a device that isn't ready to respond, which some host controllers handle poorly and never retry cleanly.
  • Copying a reference descriptor set without updating wTotalLength or endpoint addresses for a modified interface — a descriptor set that doesn't internally add up correctly is a very common source of Full-Speed enumeration failures after modifying a vendor SDK example.
  • Powering VBUS-connected peripherals immediately on cable insertion instead of gating them until after SET_CONFIGURATION, silently exceeding the 100 mA unconfigured budget.
  • Debugging by symptom alone rather than capturing a protocol trace — host-side error text describes what the OS observed, not which enumeration step actually failed; a trace turns hours of speculative firmware changes into a direct diagnosis.

Frequently Asked Questions

Why does my device show up as 'Unknown USB Device' or 'Device Descriptor Request Failed' on Windows?
This specific error means the host reset the device and sent a GET_DESCRIPTOR request for the first 8 bytes of the device descriptor, but the device never responded correctly — either it didn't respond at all (USB stack not running, D+ pull-up not enabled, or wrong clock so no valid bit timing), or it responded with malformed data (descriptor pointer or length error in firmware). This is a Full Speed signalling-layer failure, not a higher-layer driver problem — check the USB clock source and D+ pull-up enable sequence before looking at the descriptor content itself.
Can a bad VID/PID actually stop enumeration, or does it just install the wrong driver?
A VID/PID by itself doesn't stop the low-level enumeration handshake — the device still responds to descriptor requests and gets assigned an address. What a VID/PID problem breaks is driver binding: if the VID/PID matches an INF file already registered for a different device class, Windows can load the wrong driver or refuse to install one, which looks like 'enumeration failure' from the user's perspective even though the USB protocol layer succeeded. Use a USB descriptor viewer to confirm the device address was assigned and descriptors were read successfully before concluding the fault is in the descriptor content rather than the driver binding.
Does the 100 mA unconfigured current limit actually cause real failures?
Yes, and it's an easy one to miss because it only shows up under specific conditions. A device that starts charging a large VBUS bulk capacitor or powering peripheral ICs before the host completes SET_CONFIGURATION can pull more than the 100 mA unconfigured limit, tripping the host port's overcurrent protection. The port then power-cycles or disables itself, which the OS reports as a generic enumeration failure with no descriptor-level diagnostic information. Measure inrush and steady-state current draw during the enumeration window specifically, not just at the completed configured state.

References

Related Questions

Related Forum Discussions