{"record":{"id":"ce64cb24295ac85c","repo":"rqlite/rqlite","slug":"loading-snapshot-q-w","errorCode":null,"errorMessage":"loading snapshot %q: %w","messagePattern":"loading snapshot %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"snapshot/snapshot.go","lineNumber":485,"sourceCode":"// multiple data files, unreadable metadata, or a mismatch between declared kind\n// and observed file format), it returns an error describing the inconsistency.\n// Scan does not attempt to repair or modify on-disk state.\nfunc (c *SnapshotCatalog) Scan(dir string) (SnapshotSet, error) {\n\tentries, err := os.ReadDir(dir)\n\tif err != nil {\n\t\treturn SnapshotSet{}, fmt.Errorf(\"reading snapshot store directory: %w\", err)\n\t}\n\n\tvar snapshots []*Snapshot\n\tfor _, entry := range entries {\n\t\tif !entry.IsDir() || isTmpName(entry.Name()) {\n\t\t\tcontinue\n\t\t}\n\n\t\tsnapshotPath := filepath.Join(dir, entry.Name())\n\t\tsnapshot, err := c.loadSnapshot(snapshotPath, entry.Name())\n\t\tif err != nil {\n\t\t\treturn SnapshotSet{}, fmt.Errorf(\"loading snapshot %q: %w\", entry.Name(), err)\n\t\t}\n\t\tsnapshots = append(snapshots, snapshot)\n\t}\n\n\tsort.Slice(snapshots, func(i, j int) bool {\n\t\treturn snapshots[i].Less(snapshots[j])\n\t})\n\n\treturn SnapshotSet{\n\t\tdir:   dir,\n\t\titems: snapshots,\n\t}, nil\n}\n\nfunc (c *SnapshotCatalog) loadSnapshot(path string, id string) (*Snapshot, error) {\n\tmeta, err := readRaftMeta(metaPath(path))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"reading meta.json: %w\", err)","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/rqlite/rqlite/blob/7586a4d1bdbd9a5a80021664c5a863cd850adb60/snapshot/snapshot.go#L467-L503","documentation":"Scan() walks the snapshot directory and calls loadSnapshot() for each entry; if any single snapshot fails to load for any reason (bad meta.json, missing data, corrupt files, CRC errors), the entire scan fails and this wrapper adds the snapshot directory name to the underlying error.","triggerScenarios":"Calling Scan(), LatestIndexTerm(), ListAll(), Len(), or checkCRCs() when any snapshot subdirectory on disk is unreadable, incomplete, or corrupt — e.g. a partially written snapshot after a crash, or a meta.json that fails readRaftMeta().","commonSituations":"Disk full or process kill during snapshot write leaving a torn snapshot directory; manual copy/restore of snapshot dirs missing meta.json; permission problems on snapshot files; corrupted filesystem after power loss.","solutions":["Inspect the wrapped inner error and the quoted snapshot name; delete or repair the offending snapshot directory and restart","Restore the snapshot directory from a good backup or re-snapshot from a healthy node","Check filesystem permissions and disk health (dmesg, SMART) for the data directory"],"exampleFix":"// before: node fails to start due to corrupt snapshot dir\n// after: remove the bad snapshot directory\nrm -rf /path/to/data/rt-snapshot-<bad-id>\n# then restart rqlited","handlingStrategy":"try-catch","validationCode":"for _, d := range snapshotDirs { if _, err := os.Stat(filepath.Join(d, \"meta.json\")); err != nil { /* quarantine dir */ } }","typeGuard":"func loadableSnapshotDir(dir string) bool { info, err := os.Stat(dir); return err == nil && info.IsDir() }","tryCatchPattern":"ss, err := catalog.Scan()\nif err != nil {\n    var qe *QuarantineError\n    if errors.As(err, &qe) { removeBadSnapshotDir(qe.Dir); retry() }\n    return err\n}","preventionTips":["Never delete or edit files inside snapshot directories while the node runs","Copy snapshot directories atomically (write to temp dir, then rename)","Monitor disk space and use filesystems with journaling"],"tags":["snapshot","filesystem","corruption"],"backgroundTag":"snapshot-load-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"}