commaai/openpilot · warning

failed to open panda %s

Error message

failed to open panda %s

What it means

Emitted in the panda stream settings dialog (tools/cabana/streams/pandastream.cc) when constructing a Panda object for the user-selected serial throws std::exception — i.e. opening that specific panda by serial failed (claim/open USB device with that serial did not succeed). The dialog responds by clearing has_panda, disabling panda streaming and FD options for that serial.

Source

Thrown at openpilot/tools/cabana/streams/pandastream.cc:128

  for (auto serial : Panda::list()) {
    serial_edit->addItem(QString::fromStdString(serial));
  }
}

void OpenPandaWidget::buildConfigForm() {
  for (int i = form_layout->rowCount() - 1; i > 0; --i) {
    form_layout->removeRow(i);
  }

  QString serial = serial_edit->currentText();
  bool has_fd = false;
  bool has_panda = !serial.isEmpty();
  if (has_panda) {
    try {
      Panda panda(serial.toStdString());
      has_fd = (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA) || (panda.hw_type == cereal::PandaState::PandaType::RED_PANDA_V2);
    } catch (const std::exception& e) {
      fprintf(stderr, "failed to open panda %s\n", serial.toUtf8().constData());
      has_panda = false;
    }
  }

  if (has_panda) {
    config.serial = serial.toStdString();
    config.bus_config.resize(3);
    for (int i = 0; i < config.bus_config.size(); i++) {
      QHBoxLayout *bus_layout = new QHBoxLayout;

      // CAN Speed
      bus_layout->addWidget(new QLabel(tr("CAN Speed (kbps):")));
      QComboBox *can_speed = new QComboBox;
      for (int j = 0; j < std::size(speeds); j++) {
        can_speed->addItem(QString::number(speeds[j]));

        if (data_speeds[j] == config.bus_config[i].can_speed_kbps) {
          can_speed->setCurrentIndex(j);

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Confirm the panda with that serial is actually connected: `lsusb` and check the serials cabana lists (the combo repopulates from live devices).
  2. Stop other processes holding the panda (boardd, another cabana, panda flash tools) and reopen the dialog.
  3. Install/refresh openpilot udev rules so the user can open the USB device without root.
  4. Replug the panda and reopen the dialog so the serial list is rebuilt from live devices.

Example fix

# before: dialog shows serial, message printed, panda options disabled
ps aux | grep boardd   # boardd claimed the panda

# after
pkill boardd
# reopen the stream settings dialog — Panda(serial) constructs, FD options appear
Defensive patterns

Strategy: validation

Validate before calling

// Before selecting a serial in the dialog, confirm it can be opened:
#include "panda/panda.h"
bool pandaSerialOpenable(const std::string &serial) {
  try { Panda p(serial); return p.connected(); }
  catch (const std::exception &) { return false; }
}

Try / catch

// The dialog already demonstrates the pattern — wrap construction, degrade on throw:
try {
  Panda panda(serial.toStdString());
  has_fd = panda.hw_type == cereal::PandaState::PandaType::RED_PANDA /* ... */;
} catch (const std::exception &) {
  has_panda = false;  // disable panda options instead of crashing the dialog
}

Prevention

When it happens

Trigger: Opening the stream settings dialog (or changing the serial combo box, triggering the re-scan) while the selected serial cannot be opened: the device with that serial is no longer present (stale combo entry), another process (a second cabana, boardd, flasher) holds the panda's USB interface exclusively, or USB permissions deny opening the device. The try block around `Panda panda(serial.toStdString())` catches and prints, then treats the serial as unusable.

Common situations: Selecting a serial from the dropdown left over from a previous session after unplugging that panda; running boardd/cabana simultaneously — only one can claim the interface; Linux udev rules missing so the device node is root-only; panda mid-flash when the dialog opened.

Related errors


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