{"record":{"id":"ce9f79679fa533f9","repo":"rqlite/rqlite","slug":"failed-to-rename-database-s","errorCode":null,"errorMessage":"failed to rename database: %s","messagePattern":"failed to rename database: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db/swappable_db.go","lineNumber":65,"sourceCode":"\n// Swap swaps the underlying database with that at the given path. The Swap operation\n// may fail on some platforms if the file at path is open by another process. It is\n// the caller's responsibility to ensure the file at path is not in use.\nfunc (s *SwappableDB) Swap(path string, fkConstraints, walEnabled bool) error {\n\tif !IsValidSQLiteFile(path) {\n\t\treturn fmt.Errorf(\"invalid SQLite data\")\n\t}\n\n\ts.dbMu.Lock()\n\tdefer s.dbMu.Unlock()\n\tif err := s.db.Close(); err != nil {\n\t\treturn fmt.Errorf(\"failed to close: %s\", err)\n\t}\n\tif err := RemoveFiles(s.db.Path()); err != nil {\n\t\treturn fmt.Errorf(\"failed to remove files: %s\", err)\n\t}\n\tif err := os.Rename(path, s.db.Path()); err != nil {\n\t\treturn fmt.Errorf(\"failed to rename database: %s\", err)\n\t}\n\n\tdb, err := OpenWithDriver(s.drv, s.db.Path(), fkConstraints, walEnabled)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open SQLite file failed: %s\", err)\n\t}\n\ts.db = db\n\tif err := s.checkpointMgr.Close(); err != nil {\n\t\treturn fmt.Errorf(\"failed to close checkpoint manager: %s\", err)\n\t}\n\tmgr, err := NewCheckpointManager(db)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to recreate checkpoint manager: %s\", err)\n\t}\n\ts.checkpointMgr = mgr\n\treturn nil\n}\n","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/rqlite/rqlite/blob/7586a4d1bdbd9a5a80021664c5a863cd850adb60/db/swappable_db.go#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nerr := db.Swap(\"/tmp/restore.sqlite\") // /tmp on tmpfs, data on /var\n// after\nf, _ := os.CreateTemp(dataDir, \"restore-*\") // same filesystem as DB\nerr := db.Swap(f.Name())","handlingStrategy":"validation","validationCode":"func sameFS(a, b string) (bool, error) {\n    ia, ib := syscall.Stat_t{}, syscall.Stat_t{}\n    if err := syscall.Stat(filepath.Dir(a), &ia); err != nil { return false, err }\n    if err := syscall.Stat(filepath.Dir(b), &ib); err != nil { return false, err }\n    return ia.Dev == ib.Dev, nil\n}","typeGuard":null,"tryCatchPattern":"if err := db.Swap(path); err != nil {\n    if strings.Contains(err.Error(), \"failed to rename database\") {\n        return fmt.Errorf(\"ensure %s exists and shares a filesystem with the data dir\", path)\n    }\n    return err\n}","preventionTips":["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"],"tags":["filesystem","rename","restore","sqlite"],"backgroundTag":"os-rename-failed","analyzedSha":"7586a4d1bdbd9a5a80021664c5a863cd850adb60","analyzedAt":"2026-09-03T07:03:02.260Z","contentChangedAt":"2026-09-03T07:03:02.260Z","schemaVersion":2},"datasetVersion":"2026-09-10T12:17:11.382Z"}