rqlite/rqlite · error
failed to rename database: %s
Error message
failed to rename database: %s
What it means
Once old files are removed, Swap renames the new SQLite file into the canonical database path using os.Rename. A failure here (cross-device move, missing source, permission issue) aborts the swap with this error.
Source
Thrown at db/swappable_db.go:65
// Swap swaps the underlying database with that at the given path. The Swap operation
// may fail on some platforms if the file at path is open by another process. It is
// the caller's responsibility to ensure the file at path is not in use.
func (s *SwappableDB) Swap(path string, fkConstraints, walEnabled bool) error {
if !IsValidSQLiteFile(path) {
return fmt.Errorf("invalid SQLite data")
}
s.dbMu.Lock()
defer s.dbMu.Unlock()
if err := s.db.Close(); err != nil {
return fmt.Errorf("failed to close: %s", err)
}
if err := RemoveFiles(s.db.Path()); err != nil {
return fmt.Errorf("failed to remove files: %s", err)
}
if err := os.Rename(path, s.db.Path()); err != nil {
return fmt.Errorf("failed to rename database: %s", err)
}
db, err := OpenWithDriver(s.drv, s.db.Path(), fkConstraints, walEnabled)
if err != nil {
return fmt.Errorf("open SQLite file failed: %s", err)
}
s.db = db
if err := s.checkpointMgr.Close(); err != nil {
return fmt.Errorf("failed to close checkpoint manager: %s", err)
}
mgr, err := NewCheckpointManager(db)
if err != nil {
return fmt.Errorf("failed to recreate checkpoint manager: %s", err)
}
s.checkpointMgr = mgr
return nil
}
View on GitHub (pinned to 7586a4d1bd)
Solutions
- Write the restore temp file on the same filesystem as the database path
- Confirm the source file exists and hasn't been removed by a previous partial Swap
- Check write permission on the destination data directory
- Retry the restore with a fresh temp file
Example fix
// before
err := db.Swap("/tmp/restore.sqlite") // /tmp on tmpfs, data on /var
// after
f, _ := os.CreateTemp(dataDir, "restore-*") // same filesystem as DB
err := db.Swap(f.Name()) Defensive patterns
Strategy: validation
Validate before calling
func sameFS(a, b string) (bool, error) {
ia, ib := syscall.Stat_t{}, syscall.Stat_t{}
if err := syscall.Stat(filepath.Dir(a), &ia); err != nil { return false, err }
if err := syscall.Stat(filepath.Dir(b), &ib); err != nil { return false, err }
return ia.Dev == ib.Dev, nil
} Try / catch
if err := db.Swap(path); err != nil {
if strings.Contains(err.Error(), "failed to rename database") {
return fmt.Errorf("ensure %s exists and shares a filesystem with the data dir", path)
}
return err
} Prevention
- Stage restore files on the same filesystem as the data dir
- Never reuse a temp path after a failed Swap
- Check destination directory writability before restore
When it happens
Trigger: Calling Swap when the source temp file `path` no longer exists, or source and destination live on different filesystems (EXDEV), or the destination directory is not writable.
Common situations: Staging restore files on /tmp (tmpfs) while the data dir is on another mount; temp file already consumed by a prior failed Swap; insufficient directory permissions.
Related errors
- failed to remove files: %s
- error swapping database file: %v
- failed to get last modified time: %s
- ErrWALReplayDirectoryMismatch
- ErrWALAlreadyExists
AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03).
Data as JSON: /api/errors/ce9f79679fa533f9.
Report an issue: GitHub.