benbjohnson/litestream · error
cannot specify index & timestamp to restore
Error message
cannot specify index & timestamp to restore
What it means
Replica.Restore rejects mutually exclusive targeting: you may restore to a specific TXID or to a specific timestamp, but not both at once, since the two targets can conflict. Passing both a non-zero opt.TXID and a non-zero opt.Timestamp triggers this validation error before any restore work begins.
Source
Thrown at replica.go:613
}
// Replica restores the database from a replica based on the options given.
// This method will restore into opt.OutputPath, if specified, or into the
// DB's original database path. It can optionally restore from a specific
// replica or it will automatically choose the best one. Finally,
// a timestamp can be specified to restore the database to a specific
// point-in-time.
//
// When the replica contains both v0.3.x and LTX format backups, this method
// compares snapshots from both formats and uses whichever has the better backup:
// - With timestamp: uses the format with the most recent snapshot before timestamp
// - Without timestamp: uses the format with the most recent backup overall
func (r *Replica) Restore(ctx context.Context, opt RestoreOptions) (err error) {
// Validate options.
if opt.OutputPath == "" {
return fmt.Errorf("output path required")
} else if opt.TXID != 0 && !opt.Timestamp.IsZero() {
return fmt.Errorf("cannot specify index & timestamp to restore")
} else if opt.Follow && opt.TXID != 0 {
return fmt.Errorf("cannot use follow mode with -txid")
} else if opt.Follow && !opt.Timestamp.IsZero() {
return fmt.Errorf("cannot use follow mode with -timestamp")
} else if opt.IntegrityCheck != IntegrityCheckNone && opt.IntegrityCheck != IntegrityCheckQuick && opt.IntegrityCheck != IntegrityCheckFull {
return fmt.Errorf("unsupported integrity check mode: %d", opt.IntegrityCheck)
}
// In follow mode, if the database already exists, attempt crash recovery
// by reading the last applied TXID from the sidecar file.
if opt.Follow {
if _, statErr := os.Stat(opt.OutputPath); statErr == nil {
txid, readErr := ReadTXIDFile(opt.OutputPath)
if readErr != nil {
return fmt.Errorf("read txid file for crash recovery: %w", readErr)
}
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)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Choose one target: set either TXID or Timestamp in RestoreOptions, not both.
- Prefer Timestamp for point-in-time recovery; use TXID only when you know the exact transaction.
- Sanitize option-building code to zero the other field when one is selected.
Example fix
// before
opt := litestream.RestoreOptions{TXID: txid, Timestamp: ts}
err := replica.Restore(ctx, opt) // fails
// after
opt := litestream.RestoreOptions{Timestamp: ts} // or TXID, not both
err := replica.Restore(ctx, opt) Defensive patterns
Strategy: validation
Validate before calling
if opt.TXID != 0 && !opt.Timestamp.IsZero() {
return fmt.Errorf("set either TXID or Timestamp, not both")
} Try / catch
if err := replica.Restore(ctx, opt); err != nil && strings.Contains(err.Error(), "cannot specify index & timestamp") {
// rebuild options with a single target and retry
} Prevention
- Normalize restore inputs: zero out TXID when a timestamp is supplied and vice versa
- In UIs/scripts, make txid and timestamp mutually exclusive controls
- Validate RestoreOptions in a helper before invoking Restore
When it happens
Trigger: Calling Restore with RestoreOptions where TXID != 0 and Timestamp is also set — e.g. code that fills both fields from user input without checking exclusivity, or CLI/config plumbing that passes both -txid and -timestamp through.
Common situations: UIs or scripts that forward all optional restore parameters unconditionally; users specifying both a transaction and a point-in-time; EnsureExists/Run callers combining stored TXID with a computed timestamp.
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 -timestamp, must specify in ISO 8601 format (e.g. 20
- cannot specify a replica URL and the -config flag
- timestamp does not exist
- output path required
- snapshot interval must be greater than 0
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/a7e2de63382aad6c.
Report an issue: GitHub.