benbjohnson/litestream · error
no backups found
Error message
no backups found
What it means
When RestoreOptions.Timestamp is set, CalcRestoreTarget requires known time bounds (createdAt/updatedAt) to validate the requested timestamp. If both bounds are zero — meaning no backups of any format were found in the replica — restore target computation fails with 'no backups found'. It indicates the replica has nothing restorable, not that the timestamp is out of range.
Source
Thrown at replica.go:587
// Also check v0.3.x time bounds if client supports it.
if client, ok := r.Client.(ReplicaClientV3); ok {
v3CreatedAt, v3UpdatedAt, err := r.TimeBoundsV3(ctx, client)
if err != nil {
return time.Time{}, fmt.Errorf("v0.3.x time bounds: %w", err)
}
// Extend time bounds to include v0.3.x backups.
if !v3CreatedAt.IsZero() && (createdAt.IsZero() || v3CreatedAt.Before(createdAt)) {
createdAt = v3CreatedAt
}
if !v3UpdatedAt.IsZero() && (updatedAt.IsZero() || v3UpdatedAt.After(updatedAt)) {
updatedAt = v3UpdatedAt
}
}
// Skip if it does not contain timestamp.
if !opt.Timestamp.IsZero() {
if createdAt.IsZero() && updatedAt.IsZero() {
return time.Time{}, fmt.Errorf("no backups found")
}
if opt.Timestamp.Before(createdAt) || opt.Timestamp.After(updatedAt) {
return time.Time{}, fmt.Errorf("timestamp does not exist")
}
}
return updatedAt, nil
}
// 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:View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify the replica actually has backups: run `litestream ltx` / list the storage location.
- Check the config's bucket/prefix/replica path points to the location containing backups.
- Run a sync (`litestream replicate`) to create an initial backup before restoring.
- If backups were deleted by retention/lifecycle policies, restore from a different replica or snapshot.
Defensive patterns
Strategy: validation
Validate before calling
// check the replica has backups before a timestamped restore
infos, err := client.ListLTXFiles(ctx, 0)
if err != nil || len(infos) == 0 {
return fmt.Errorf("replica %s has no backups", replicaName)
} Try / catch
err := replica.Restore(ctx, opt)
if err != nil && errors.Is(err, errors.New("no backups found")) || strings.Contains(err.Error(), "no backups found") {
// fall back to another replica or create a fresh backup first
} Prevention
- Confirm backups exist with `litestream ltx` before planning restores
- Verify bucket/prefix/replica name in config points at the populated location
- Watch for lifecycle policies deleting objects litestream still references
When it happens
Trigger: CalcRestoreTarget (and thus restore with -timestamp) is called on a replica whose storage contains no LTX files and no legacy backups, so TimeBounds/TimeBoundsV3 returned zero timestamps.
Common situations: Typo in config bucket/prefix pointing at an empty location; a replica that never completed its first sync; storage cleaned by lifecycle policies; using the wrong replica name in restore command.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- invalid -timestamp, must specify in ISO 8601 format (e.g. 20
- database already exists, skipping
- no snapshots available
- too many arguments
- invalid -integrity-check value: %s
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/2d9ad2dac1a20b16.
Report an issue: GitHub.