commaai/openpilot · error · RuntimeError
chestnut did not enumerate within {timeout:g}s
Error message
chestnut did not enumerate within {timeout:g}s What it means
Raised by Flash.connect() when, within the timeout window (default 5.0s, polled every 0.1s), find_chestnut() never returns a usable device path. The script scanned /sys/bus/usb/devices/* for the known VID:PID pairs (3801:0001/add1:0001 runtime, 174c:2464/2463 ROM) and found nothing - the chestnut bridge is not enumerated on USB.
Source
Thrown at openpilot/system/hardware/chestnut/flash.py:166
self.fd = -1
def close(self):
if self.fd >= 0:
os.close(self.fd)
self.fd = -1
def connect(self, timeout=5.0):
self.close()
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
path, vid_pid, product = find_chestnut()
if in_rom_bootloader(vid_pid, product):
raise RomFallback("chestnut fell back to the ROM bootloader")
if path is not None:
self.fd = claim_interface(path)
return
time.sleep(0.1)
raise RuntimeError(f"chestnut did not enumerate within {timeout:g}s")
def reg_write(self, addr, value):
fcntl.ioctl(self.fd, USBDEVFS_CONTROL,
Ctrl(0x40, 0xE5, addr & 0xFFFF, value & 0xFFFF, 0, 2000, None))
def reg_read(self, addr, length=1):
buf = (ctypes.c_ubyte * length)()
fcntl.ioctl(self.fd, USBDEVFS_CONTROL,
Ctrl(0xC0, 0xE4, addr & 0xFFFF, 0, length, 2000, ctypes.cast(buf, ctypes.c_void_p)))
return bytes(buf)
def write_buffer(self, data):
for i, value in enumerate(data):
self.reg_write(0x7000 + i, value)
def wait_controller(self, timeout=2.0):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:View on GitHub (pinned to 516ec1e682)
Solutions
- Check /sys/bus/usb/devices and lsusb for any 3801:0001, add1:0001 or 174c:2464 entry; if absent, reseat the USB-C cable and enclosure and retry
- Pass a longer timeout: flash.connect(timeout=15.0) for slow-enumerating or just-reset devices
- If a USBDEVFS_RESET was just issued, wait for re-enumeration before connecting (the ROM path sleeps 3 seconds)
- Try a different port/cable, ideally a direct connection to the host controller, no hubs
Example fix
# before flash.connect() # 5s default too short after reset # after flash.connect(timeout=15.0)
Defensive patterns
Strategy: retry
Validate before calling
from flash import find_chestnut
if find_chestnut()[0] is None:
raise SystemExit('chestnut not on USB bus - check cable/power before continuing') Try / catch
try:
flash.connect(timeout=15.0)
except RuntimeError as e:
if 'did not enumerate' in str(e):
reseat_and_retry()
raise Prevention
- Verify the device appears in lsusb before launching the flasher
- Use generous timeouts after port resets or replugs
- Prefer direct host-controller ports over hubs
When it happens
Trigger: Flash.connect(timeout) called when the enclosure is unplugged or powered off (no VBUS), the USB-C cable/port is bad, the device is enumerating slowly after a port reset/replug and the 5s deadline expires, or the device is in a VID:PID not in the table.
Common situations: Cable or dock that does not carry data; wrong USB port on the host; device still booting after power-on; a hub hiding the device; device that hard-hung and needs a physical replug; racing connect() immediately after a port reset (rom_write sleeps 3s for exactly this reason).
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- flash did not converge within {FLASH_BUDGET:g}s
- flash controller timeout
- chestnut disappeared before recovery
- AT command timed out
- write failed: {e}
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/0e4f8e713a42dd95.
Report an issue: GitHub.