benbjohnson/litestream · error

iterate snapshots for crash recovery validation

Error message

iterate snapshots for crash recovery validation: %w

What it means

While iterating snapshots for follow-mode crash recovery validation, the iterator reported an error after iteration (itr.Err). The remote listing partially failed, so the saved TXID's reachability could not be confirmed.

Solutions

  1. Check replica backend health
  2. Restart litestream to retry validation
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at replica.go:647 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/67740bc075c258e6. Report an issue: GitHub.

Appendix: source

Thrown at replica.go:647

			}
			if txid == 0 {
				return fmt.Errorf("cannot resume follow mode: database exists but no -txid file found; delete the database to re-restore: %s", opt.OutputPath)
			}
			// Validate saved TXID is still reachable. If the earliest snapshot
			// starts after our saved TXID, retention has pruned the history
			// and we can't catch up incrementally.
			snapshotItr, itrErr := r.Client.LTXFiles(ctx, SnapshotLevel, 0, false)
			if itrErr != nil {
				return fmt.Errorf("cannot validate saved TXID for crash recovery: %w", itrErr)
			}

			var latestSnapshot *ltx.FileInfo
			for snapshotItr.Next() {
				latestSnapshot = snapshotItr.Item()
			}
			if err := snapshotItr.Err(); err != nil {
				_ = snapshotItr.Close()
				return fmt.Errorf("iterate snapshots for crash recovery validation: %w", err)
			}
			_ = snapshotItr.Close()

			if latestSnapshot != nil {
				if latestSnapshot.MinTXID > txid {
					return fmt.Errorf("cannot resume follow mode: saved TXID %s is behind the earliest snapshot (min TXID %s); replica history has been pruned -- delete %s and %s-txid to re-restore", txid, latestSnapshot.MinTXID, opt.OutputPath, opt.OutputPath)
				}
				if txid > latestSnapshot.MaxTXID {
					return fmt.Errorf("cannot resume follow mode: saved TXID %s is ahead of latest snapshot (max TXID %s); delete %s and %s-txid to re-restore", txid, latestSnapshot.MaxTXID, opt.OutputPath, opt.OutputPath)
				}
			}

			r.Logger().Info("resuming follow mode from crash recovery", "txid", txid, "output", opt.OutputPath)
			return r.follow(ctx, opt.OutputPath, txid, opt.FollowInterval)
		}
	}

	// Ensure output path does not already exist.

View on GitHub (pinned to 4ed7a308f6)