commaai/openpilot · error

failed to create temporary Cabana settings %s: %s

Error message

failed to create temporary Cabana settings %s: %s

What it means

Emitted by saveSettings() in tools/cabana/settings.cc when mkstemp() on '<cabana.json>.tmp.XXXXXX' returns a negative fd. Save uses a write-to-temp + rename pattern for atomicity; this message means the temporary file itself could not be created, so nothing was written and saveSettings returns false.

Source

Thrown at openpilot/tools/cabana/settings.cc:115

bool writeAll(int fd, const std::string &data) {
  size_t written = 0;
  while (written < data.size()) {
    ssize_t result = write(fd, data.data() + written, data.size() - written);
    if (result < 0 && errno == EINTR) continue;
    if (result <= 0) return false;
    written += result;
  }
  return true;
}

bool saveSettings(const json11::Json::object &settings_json) {
  const auto path = settingsFile();
  const std::string contents = json11::Json(settings_json).dump();
  std::string temporary_path = path.string() + ".tmp.XXXXXX";
  int fd = mkstemp(temporary_path.data());
  if (fd < 0) {
    fprintf(stderr, "failed to create temporary Cabana settings %s: %s\n", temporary_path.c_str(), strerror(errno));
    return false;
  }

  bool success = writeAll(fd, contents) && fsync(fd) == 0;
  if (close(fd) < 0) success = false;
  if (success && rename(temporary_path.c_str(), path.c_str()) < 0) success = false;

  if (success) {
    int dir_fd = open(path.parent_path().c_str(), O_RDONLY | O_CLOEXEC);
    success = dir_fd >= 0 && fsync(dir_fd) == 0;
    if (dir_fd >= 0 && close(dir_fd) < 0) success = false;
  }

  if (!success) {
    const int saved_errno = errno;
    unlink(temporary_path.c_str());
    fprintf(stderr, "failed to save Cabana settings to %s: %s\n", path.c_str(), strerror(saved_errno));
  }

View on GitHub (pinned to 516ec1e682)

Solutions

  1. Confirm the config directory exists and is writable: `mkdir -p <configPath> && touch <configPath>/cabana.json.tmp.test && rm <configPath>/cabana.json.tmp.test`.
  2. Free disk space / inodes if the message's strerror says 'No space left on device'.
  3. Run cabana as the user who owns the config dir, or fix ownership.
  4. Handle the return value: saveSettings() returning false is expected to be non-fatal; settings just won't persist this session.

Example fix

// before
// stderr: failed to create temporary Cabana settings /home/user/.comma/cabana.json.tmp.AbC123: Permission denied

# after (fix the environment)
sudo chown -R $USER:$USER /home/user/.comma
cabana  # settings save succeeds
Defensive patterns

Strategy: validation

Validate before calling

// Before triggering a save (e.g. before relying on settings persistence),
// confirm mkstemp can create a temp file in the config dir:
bool canCreateTempIn(const std::filesystem::path &dir) {
  std::string tmpl = (dir / "cabana.tmp.XXXXXX").string();
  int fd = mkstemp(tmpl.data());
  if (fd < 0) return false;
  unlink(tmpl.c_str());
  close(fd);
  return true;
}

Prevention

When it happens

Trigger: saveSettings() reaching mkstemp(path.string() + ".tmp.XXXXXX") when the config directory does not exist, is not writable by the current user, the filesystem is full (no inode/space), or a filesystem error like EDQUOT/EROFS occurs. Note the string passed to mkstemp must be modifiable — it is, via .data() on a std::string — so the failure is environmental, not an API misuse.

Common situations: ensureSettingsDirectory() failed earlier (see error 141) but save was attempted anyway; running cabana under a user without write access to ~/.comma; disk-full on a long session that saves settings on every change; SELinux/AppArmor denying writes to the config dir.

Related errors


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