benbjohnson/litestream · error

cannot use -dry-run with -f

Error message

cannot use -dry-run with -f

What it means

This error is thrown by RestoreCommand.dryRunPlan because -dry-run (which computes and prints a restore plan without restoring) and -f/-follow (which continuously restores as new WAL frames arrive) are mutually exclusive modes. A dry run produces a one-shot static plan, while follow mode never terminates, so combining them is meaningless. The command rejects the combination up front before contacting the replica.

Source

Thrown at cmd/litestream/restore.go:198

	Level     int    `json:"level"`
	Name      string `json:"name"`
	MinTXID   string `json:"min_txid"`
	MaxTXID   string `json:"max_txid"`
	Size      int64  `json:"size"`
	Timestamp string `json:"timestamp"`
}

type RestoreResult struct {
	DBPath         string `json:"db_path"`
	Replica        string `json:"replica"`
	TXID           string `json:"txid"`
	DurationMS     int64  `json:"duration_ms"`
	IntegrityCheck string `json:"integrity_check"`
}

func (c *RestoreCommand) dryRunPlan(ctx context.Context, source string, r *litestream.Replica, opt litestream.RestoreOptions) (RestorePlan, error) {
	if opt.Follow {
		return RestorePlan{}, fmt.Errorf("cannot use -dry-run with -f")
	}

	infos, err := litestream.CalcRestorePlan(ctx, r.Client, opt.TXID, opt.Timestamp, r.Logger())
	if err != nil {
		return RestorePlan{}, err
	}
	if len(infos) == 0 {
		return RestorePlan{}, litestream.ErrTxNotAvailable
	}

	plan := RestorePlan{
		Source:     source,
		TargetPath: opt.OutputPath,
		Replica:    r.Client.Type(),
		MinTXID:    infos[0].MinTXID.String(),
		MaxTXID:    infos[len(infos)-1].MaxTXID.String(),
		Files:      make([]RestorePlanFile, 0, len(infos)),
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Remove the -f/-follow flag when using -dry-run
  2. If you want continuous restore, drop -dry-run and run the restore normally with -f
  3. If you want a preview, run once with -dry-run (no -f), then run the real restore separately

Example fix

// before
litestream restore -o restored.db -dry-run -f /path/to/db
// after
litestream restore -o restored.db -dry-run /path/to/db
Defensive patterns

Strategy: validation

Validate before calling

if dryRun && follow {
    return fmt.Errorf("-dry-run and -f are mutually exclusive")
}
litestream restore -o out.db -dry-run /path/to/db

Try / catch

if err := cmd.Run(ctx); err != nil {
    if strings.Contains(err.Error(), "cannot use -dry-run with -f") {
        // retry without -f or without -dry-run
    }
    return err
}

Prevention

When it happens

Trigger: Running `litestream restore -dry-run -f <db path>` (or setting both DryRun and Follow in the RestoreCommand flags), which makes Run call dryRunPlan with opt.Follow == true.

Common situations: A user scripting a plan preview adds -f out of habit from interactive restores; a wrapper script that always appends -f; confusion between 'show me what would be restored' and 'keep restoring' semantics.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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