commaai/openpilot · error · SerialException
could not open port {self._port}: {e}
Error message
could not open port {self._port}: {e} What it means
Serial.open() maps an OSError from os.open() on the device path to SerialException. Typical errno values: ENOENT (device node missing), EACCES (no permission), EBUSY (opened exclusively elsewhere). The message includes the port path and the OS error string.
Source
Thrown at openpilot/common/serial.py:74
@property
def dtr(self) -> bool:
return self._dtr
@dtr.setter
def dtr(self, value: bool) -> None:
self._dtr = bool(value)
if self._fd >= 0:
self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr)
def open(self) -> None:
if self._fd >= 0:
return
try:
self._fd = os.open(self._port, os.O_RDWR | os.O_NOCTTY | os.O_NONBLOCK)
except OSError as e:
self._fd = -1
raise SerialException(e.errno, f"could not open port {self._port}: {e}") from e
try:
if self._exclusive:
try:
fcntl.flock(self._fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError as e:
raise SerialException(e.errno, f"could not exclusively lock port {self._port}: {e}") from e
self._configure()
# When not using hardware DSR/DTR handshaking, drive lines ourselves.
if not self._dsrdtr:
try:
self._set_line(TIOCM_DTR, _TIOCM_DTR, self._dtr)
if not self._rtscts:
self._set_line(TIOCM_RTS, _TIOCM_RTS, True)
except OSError as e:
if e.errno not in (errno.EINVAL, errno.ENOTTY):View on GitHub (pinned to 516ec1e682)
Solutions
- Check the port exists (ls /dev/ttyUSB* /dev/ttyACM*) and matches the device actually present
- Fix permissions: add user to dialout group or adjust udev rules
- Retry open with a short delay at startup — the kernel may not have created the node yet
Defensive patterns
Strategy: retry
Validate before calling
import os
def port_ready(port: str) -> bool:
return os.path.exists(port) and os.access(port, os.O_RDWR) Try / catch
for _ in range(10):
try:
ser.open()
break
except SerialException:
time.sleep(0.5) Prevention
- Add user to dialout group; verify udev rules
- Use stable device paths (by-id) instead of /dev/ttyUSB0
- Retry open briefly at startup while the kernel creates the node
When it happens
Trigger: open() on /dev/ttyUSB*, /dev/ttyACM*, or a socat/ptsy path that does not exist, is permission-denied, or is locked by another process.
Common situations: Wrong device path after replug (ttyUSB0 became ttyUSB1); user not in dialout group; udev not created the node yet at open time; another process holds the port.
Related errors
- could not exclusively lock port {self._port}: {e}
- read failed: {e}
- write failed: {e}
- write returned 0
- AT command timed out
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/dd03ffaaf00f813c.
Report an issue: GitHub.