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
- Remove the -f/-follow flag when using -dry-run
- If you want continuous restore, drop -dry-run and run the restore normally with -f
- 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
- Remember -dry-run is one-shot; -f is continuous — never combine
- In wrapper scripts, add the -f flag only when not in preview mode
- Validate flag combinations in CI scripts before invoking the CLI
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
- invalid -integrity-check value: %s
- cannot specify a replica URL and the -config flag
- invalid -timestamp, must specify in ISO 8601 format (e.g. 20
- cannot specify a replica URL and the -config flag
- cannot specify -once flag with -exec
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/77f6b0521a05f814.
Report an issue: GitHub.