commaai/openpilot · error

Failed to get interface index for %s

Error message

Failed to get interface index for %s

What it means

Emitted by SocketCanStream::connect() when ioctl(sock_fd, SIOCGIFINDEX, &ifr) fails after a successful socket() — the kernel could not resolve config.device (the interface name typed in the stream settings) to an interface index. The socket is closed, sock_fd reset to -1, and connect() returns false.

Source

Thrown at openpilot/tools/cabana/streams/socketcanstream.cc:59

  ::close(fd);
  return true;
}

bool SocketCanStream::connect() {
  sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
  if (sock_fd < 0) {
    fprintf(stderr, "Failed to create CAN socket\n");
    return false;
  }

  // Enable CAN-FD
  int fd_enable = 1;
  setsockopt(sock_fd, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &fd_enable, sizeof(fd_enable));

  struct ifreq ifr = {};
  strncpy(ifr.ifr_name, config.device.c_str(), IFNAMSIZ - 1);
  if (ioctl(sock_fd, SIOCGIFINDEX, &ifr) < 0) {
    fprintf(stderr, "Failed to get interface index for %s\n", config.device.c_str());
    ::close(sock_fd);
    sock_fd = -1;
    return false;
  }

  struct sockaddr_can addr = {};
  addr.can_family = AF_CAN;
  addr.can_ifindex = ifr.ifr_ifindex;
  if (bind(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    fprintf(stderr, "Failed to bind CAN socket\n");
    ::close(sock_fd);
    sock_fd = -1;
    return false;
  }

  // Set read timeout so the thread can check for interruption
  struct timeval tv = {.tv_sec = 0, .tv_usec = 100000};  // 100ms
  setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Run `ip link show` (or `ifconfig -a`) and copy the exact interface name (e.g. can0) into the device field.
  2. Bring the interface up: `sudo ip link set can0 up type can bitrate 500000` (or your bus's rate); if the adapter is missing, plug it in and re-check.
  3. Trim whitespace and stay under 15 chars (IFNAMSIZ-1) — longer names are silently truncated by the strncpy before the ioctl.
  4. For bench testing without hardware, create a virtual bus: `sudo ip link add dev vcan0 type vcan && sudo ip link set vcan0 up` and use vcan0.

Example fix

# before
# stderr: Failed to get interface index for can1   (host only has can0)
ip link   # shows: can0

# after
# set cabana SocketCAN device to: can0
sudo ip link set can0 up type can bitrate 500000
cabana   # ioctl(SIOCGIFINDEX) resolves, bind proceeds
Defensive patterns

Strategy: validation

Validate before calling

// Verify the interface exists (and is CAN) before starting the stream:
#include <net/if.h>
#include <sys/ioctl.h>
bool canInterfaceExists(const std::string &ifname) {
  if (ifname.empty() || ifname.size() >= IFNAMSIZ) return false;  // strncpy truncates at IFNAMSIZ-1
  int fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
  if (fd < 0) return false;
  ifreq ifr = {};
  strncpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ - 1);
  bool ok = ioctl(fd, SIOCGIFINDEX, &ifr) == 0;
  ::close(fd);
  return ok;
}

Prevention

When it happens

Trigger: Starting a SocketCAN stream with a `config.device` string that does not match any network interface: typo ('can0' vs 'can1', trailing space), the CAN interface not brought up yet (`ip link set can0 up` missing), USB CAN adapter not plugged/enumerated so no canX exists, or a name longer than IFNAMSIZ-1 truncated by the strncpy. Note strncpy copies IFNAMSIZ-1 bytes, so names at the limit silently truncate and resolve to nothing.

Common situations: Typing the wrong interface name in cabana's SocketCAN device field; slcan/socketcand adapter not yet attached; interface named differently on this host (can1, vcan0 for virtual); whitespace copied into the device field.

Related errors


AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15). Data as JSON: /api/errors/8bce9ca1dec87425. Report an issue: GitHub.