rqlite/rqlite · error

no snapshot to upgrade in old snapshots directory %s

Error message

no snapshot to upgrade in old snapshots directory %s

What it means

Upgrade7To8 found a non-empty old (v7) snapshots directory but getNewest7Snapshot returned no readable snapshot metadata, so there is nothing to upgrade. This is an internal-consistency violation: the earlier empty-directory check passed, yet no subdirectory contained a valid meta.json that could be parsed into Raft snapshot metadata. It signals that the old directory contains unexpected content or corrupted/partial snapshot directories.

Source

Thrown at snapshot/upgrader.go:92

			return fmt.Errorf("failed to remove old snapshot directory %s: %s", old, err)
		}
		logger.Printf("removed old snapshot directory %s as no upgrade is needed", old)
		return nil
	}

	// Start the upgrade process.
	if err := os.MkdirAll(newTmpDir, 0755); err != nil {
		return fmt.Errorf("failed to create temporary snapshot directory %s: %s", newTmpDir, err)
	}

	oldMeta, err := getNewest7Snapshot(old)
	if err != nil {
		return fmt.Errorf("failed to get newest snapshot from old snapshots directory %s: %s", old, err)
	}
	if oldMeta == nil {
		// No snapshot to upgrade, this shouldn't happen since we checked for an empty old
		// directory earlier.
		return fmt.Errorf("no snapshot to upgrade in old snapshots directory %s", old)
	}

	// Write out the new meta file in the new snapshot directory.
	newSnapshotPath := filepath.Join(newTmpDir, oldMeta.ID)
	if err := os.MkdirAll(newSnapshotPath, 0755); err != nil {
		return fmt.Errorf("failed to create new snapshot directory %s: %s", newSnapshotPath, err)
	}
	if err := writeMeta(newSnapshotPath, oldMeta); err != nil {
		return fmt.Errorf("failed to write new snapshot meta file to %s: %s", newSnapshotPath, err)
	}

	// Ensure all file handles are closed before any directory is renamed or removed.
	if err := func() error {
		// Write SQLite database file into new snapshot dir.
		newSqlitePath := filepath.Join(newTmpDir, oldMeta.ID+".db")
		newSqliteFd, err := os.Create(newSqlitePath)
		if err != nil {
			return fmt.Errorf("failed to create new SQLite file %s: %s", newSqlitePath, err)

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Inspect the old snapshots directory and confirm each subdirectory contains a valid meta.json; remove stray or corrupted subdirectories.
  2. If the snapshots are not needed, delete or empty the old directory so Upgrade7To8 takes the clean empty-directory path.
  3. Restore the node's data directory from a known-good backup or re-bootstrap/restore via /boot, since the snapshot store is unrecoverable as-is.
  4. Check for a race where another process removed snapshot files while the upgrade was running; run the upgrade on a quiesced node.

Example fix

// before (stray empty dir in old snapshots path blocks clean state)
//  snapshots/v7/<stray-dir>/  (no meta.json)
// after
//  remove stray dirs so 'old' is either empty (clean skip) or contains only
//  valid v7 snapshots: rm -rf /path/node/data/rsnapshots/v7/<stray-dir>
Defensive patterns

Strategy: validation

Validate before calling

// Go: before relying on the upgrade path, verify the old dir holds valid v7 snapshots
func hasValidV7Snapshot(dir string) bool {
	entries, err := os.ReadDir(dir)
	if err != nil { return false }
	for _, e := range entries {
		if e.IsDir() && fsutil.FileExists(filepath.Join(dir, e.Name(), "meta.json")) {
			return true
		}
	}
	return false
}
// if dir exists, non-empty, and !hasValidV7Snapshot(dir): data dir is corrupt — restore before upgrading

Prevention

When it happens

Trigger: Calling snapshot.Upgrade7To8(old, new, logger) where 'old' is non-empty but every subdirectory either lacks meta.json, has a malformed/unparseable meta.json, or is not actually a v7 snapshot directory (readRaftMeta fails or is skipped via FileExists check).

Common situations: Upgrading a rqlite node from v7 to v8+ where the data directory was partially deleted, manually edited, or copied incompletely; stray non-snapshot subdirectories placed inside the snapshots path; leftover directories whose meta.json was lost after a crash or disk-full event.

Related errors


AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03). Data as JSON: /api/errors/5e897b8ea0d9d96a. Report an issue: GitHub.