{"record":{"id":"ed605f2ab0cd2610","repo":"commaai/openpilot","slug":"failed-to-bind-can-socket","errorCode":null,"errorMessage":"Failed to bind CAN socket\n","messagePattern":"Failed to bind CAN socket\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"openpilot/tools/cabana/streams/socketcanstream.cc","lineNumber":69,"sourceCode":"\n  // Enable CAN-FD\n  int fd_enable = 1;\n  setsockopt(sock_fd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_enable, sizeof(fd_enable));\n\n  struct ifreq ifr = {};\n  strncpy(ifr.ifr_name, config.device.c_str(), IFNAMSIZ - 1);\n  if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0) {\n    fprintf(stderr, \"Failed to get interface index for %s\\n\", config.device.c_str());\n    ::close(sock_fd);\n    sock_fd = -1;\n    return false;\n  }\n\n  struct sockaddr_can addr = {};\n  addr.can_family = AF_CAN;\n  addr.can_ifindex = ifr.ifr_ifindex;\n  if (bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {\n    fprintf(stderr, \"Failed to bind CAN socket\\n\");\n    ::close(sock_fd);\n    sock_fd = -1;\n    return false;\n  }\n\n  // Set read timeout so the thread can check for interruption\n  struct timeval tv = {.tv_sec = 0, .tv_usec = 100000};  // 100ms\n  setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));\n\n  return true;\n}\n\nvoid SocketCanStream::streamThread() {\n  struct canfd_frame frame;\n\n  while (!exit_) {\n    ssize_t nbytes = read(sock_fd, &frame, sizeof(frame));\n    if (nbytes <= 0) continue;","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/tools/cabana/streams/socketcanstream.cc#L51-L87","documentation":"Emitted by SocketCanStream::connect() when bind(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) fails after the interface index was resolved — the socket could not be attached to the selected CAN interface. addr.can_family is AF_CAN and can_ifindex comes from the prior SIOCGIFINDEX, so failure here is about interface state or privileges, not the name.","triggerScenarios":"connect() reaching bind() when the interface is down (ENETDOWN — binding a CAN_RAW socket to a downed interface), permissions denied (EACCES without CAP_NET_RAW for this operation), or the interface vanished between the ioctl and the bind (ENODEV race after unplugging the USB-CAN adapter). The fd is closed and sock_fd reset to -1.","commonSituations":"Adapter present and named correctly but never brought up (`ip link set canX up` skipped); interface went down due to a CAN bus error state (bus-off) before cabana connected; unplugging the adapter at the exact moment of connect; running unprivileged without CAP_NET_RAW.","solutions":["Bring the interface up before connecting: `sudo ip link set can0 up` (and verify state UP in `ip link show can0`).","If the adapter keeps dropping to bus-off, check wiring/termination and the configured bitrate, then `ip link set can0 down && ip link set can0 up type can bitrate <rate>` to restart it.","Grant CAP_NET_RAW (`setcap cap_net_raw+ep <cabana binary>`) if strerror said 'Permission denied'.","Reconnect the adapter and retry — an ENODEV race resolves once the interface is back."],"exampleFix":"# before\n# stderr: Failed to bind CAN socket\nip link show can0   # 'state DOWN'\n\n# after\nsudo ip link set can0 up\ncabana   # bind(sock_fd, {AF_CAN, ifindex}) succeeds, stream starts","handlingStrategy":"validation","validationCode":"// Check the interface is UP before bind():\n#include <net/if.h>\n#include <sys/ioctl.h>\nbool canInterfaceUp(const std::string &ifname, int sock_fd) {\n  ifreq ifr = {};\n  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);\n  if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) != 0) return false;\n  return (ifr.ifr_flags & IFF_UP) != 0;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always `ip link set canX up` with the correct bitrate before starting a SocketCAN stream.","Watch for bus-off: a CAN interface that errored out goes down and bind fails with ENETDOWN — restart the interface.","Grant CAP_NET_RAW if bind reports EACCES.","If the adapter is hot-pluggable, retry connect once after it re-enumerates to beat ENODEV races."],"tags":["socketcan","bind","interface","linux","can"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}