commaai/openpilot · error
failed to save Cabana settings to %s: %s
Error message
failed to save Cabana settings to %s: %s
What it means
Catch-all failure report at the end of saveSettings() in tools/cabana/settings.cc. It fires when any stage of the atomic save after temp-file creation failed: writeAll() (partial/failed write), fsync(fd), close(fd), rename(temp -> cabana.json), or the directory open/fsync that durably records the rename. The temp file is unlinked and false returned. Note the errno printed is whatever errno happened to hold, which after close/fsync failures may not identify the first failing step.
Source
Thrown at openpilot/tools/cabana/settings.cc:132
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));
}
return success;
}
bool preserveCorruptSettings() {
const auto path = settingsFile();
auto backup = path;
backup += ".corrupt";
for (int i = 1; std::filesystem::exists(backup); ++i) {
backup = path;
backup += ".corrupt." + std::to_string(i);
}
if (rename(path.c_str(), backup.c_str()) < 0) {
fprintf(stderr, "failed to preserve corrupt Cabana settings %s: %s\n", path.c_str(), strerror(errno));
return false;
}
fprintf(stderr, "preserved corrupt Cabana settings at %s\n", backup.c_str());
return true;View on GitHub (pinned to 516ec1e682)
Solutions
- Check disk space first: `df -h <configPath>` — ENOSPC during writeAll is the most frequent cause.
- If strerror is 'Input/output error', suspect the underlying storage/mount (fsck, remount, replace media).
- Verify the config directory still exists and is writable at save time; re-run ensureSettingsDirectory() before retrying.
- Retry the save — settings are written on change, so transient failures self-heal on the next modification once space is freed.
Example fix
# before # stderr: failed to save Cabana settings to /home/user/.comma/cabana.json: No space left on device df -h /home/user # 100% full # after clean up space (journal, cores, old drives), then change any setting in cabana to force a re-save
Defensive patterns
Strategy: retry
Validate before calling
// Cheap pre-save check: space and writability of the target dir
#include <sys/statvfs.h>
bool dirReadyForAtomicSave(const std::filesystem::path &dir, size_t needed = 65536) {
struct statvfs st;
if (statvfs(dir.c_str(), &st) != 0) return false;
return st.f_bavail * st.f_frsize > needed && (st.f_flag & ST_RDONLY) == 0;
} Prevention
- Monitor disk space — ENOSPC during writeAll is the top cause of this failure.
- If a save fails, change any setting again after freeing space; saves are idempotent full rewrites.
- On flaky storage (USB/NFS), move the config dir to local disk or fix the mount before long sessions.
When it happens
Trigger: saveSettings() where mkstemp succeeded but one of these fails: write() loop returns <= 0 (ENOSPC, EIO), fsync() != 0, close() < 0, rename() < 0 (cross-device is impossible here since temp is in the same dir, but permission/dir-removed races apply), or open(parent_path, O_RDONLY)/fsync(dir_fd) fails. Any one flips `success` to false and reaches the fprintf with saved_errno captured just before the unlink.
Common situations: Disk fills up mid-write (ENOSPC in writeAll — most common); flaky USB/NFS mount returning EIO on fsync; config directory deleted between ensureSettingsDirectory and rename; errno ambiguity making the message misleading after the close/fsync branch.
Related errors
- failed to create temporary Cabana settings %s: %s
- failed to preserve corrupt Cabana settings %s: %s
- failed to lock Cabana settings %s: %s
- failed to read Cabana settings %s%s%s
- failed to create Cabana settings directory %s: %s
AI-assisted analysis of commaai/openpilot@516ec1e682 (2026-08-15).
Data as JSON: /api/errors/ae7c52ce9196aa9b.
Report an issue: GitHub.