rqlite/rqlite · error

reading reap plan: %w

Error message

reading reap plan: %w

What it means

reapInternal found an existing reap-plan file (evidence of a previously interrupted reap) and attempted to resume by reading it with plan.ReadFromFile; that read failed, wrapped via %w. The plan file is corrupt or unreadable, blocking recovery of the interrupted reap.

Source

Thrown at snapshot/store.go:535

	stats.Get(reapWALs).(*expvar.Int).Set(int64(c))
	s.observers.notify(ReapObservation{
		SnapshotsReaped: n,
		WALsReaped:      c,
		Duration:        time.Since(startTime),
	})
	return n, c, nil
}

// reapInternal performs the actual reap logic. The caller must hold the write lock.
func (s *Store) reapInternal() (int, int, error) {
	// If a reap plan file exists, that means a previous reap must have encountered an error.
	// Let's make sure it is completed before we start a new reap.
	if fsutil.FileExists(s.reapPlanPath) {
		s.logger.Printf("found interrupted reap plan at %s, resuming", s.reapPlanPath)
		stats.Add(reapPlanRecovered, 1)
		p, err := plan.ReadFromFile(s.reapPlanPath)
		if err != nil {
			return 0, 0, fmt.Errorf("reading reap plan: %w", err)
		}
		return s.executeReapPlan(p, s.reapPlanPath)
	} else {
		// A reap reads and rewrites the data files, so verify their integrity
		// first (runs at most once over the Store's lifetime). We only do this if
		// a reap wasn't previously interrupted (by a crash most likely), as an
		// interrupted reap leaves data in an undefined state. On corruption this
		// hard exits in production via fatalFn; with fatalFn disabled (tests) the
		// error is returned.
		if err := s.ensureVerified(); err != nil {
			return 0, 0, err
		}
	}

	// Scan store.
	snapSet, err := s.getSnapshots()
	if err != nil {
		return 0, 0, err

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Inspect the reap plan file for corruption (truncated/partial JSON)
  2. After confirming snapshot integrity, remove the stale plan file so a fresh reap can proceed
  3. Check disk and permission health in the snapshot store directory
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at snapshot/store.go:535 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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