benbjohnson/litestream · error
find LTX snapshot: %w
Error message
find LTX snapshot: %w
What it means
Wraps an error from findBestLTXSnapshotForTimestamp during timestamp-based restore format selection. Listing LTX snapshot-level files (level-sorted, filtered by CreatedAt < timestamp) failed, so Litestream cannot compare LTX against the v0.3.x candidate.
Source
Thrown at replica.go:1434
}
// If no LTX backups exist, use v0.3.x.
if ltxUpdatedAt.IsZero() {
r.Logger().Debug("using v0.3.x restore (no LTX backups)")
return true, nil
}
// Both formats have backups - compare based on timestamp or latest.
if !timestamp.IsZero() {
// With timestamp: use format with best snapshot before timestamp.
v3Snapshot, err := r.findBestV3SnapshotForTimestamp(ctx, client, timestamp)
if err != nil {
return false, fmt.Errorf("find v0.3.x snapshot: %w", err)
}
ltxSnapshot, err := r.findBestLTXSnapshotForTimestamp(ctx, timestamp)
if err != nil {
return false, fmt.Errorf("find LTX snapshot: %w", err)
}
if v3Snapshot != nil && (ltxSnapshot == nil || v3Snapshot.CreatedAt.After(ltxSnapshot.CreatedAt)) {
r.Logger().Debug("using v0.3.x restore (better snapshot for timestamp)",
"v3_snapshot", v3Snapshot.CreatedAt,
"ltx_snapshot", ltxSnapshot)
return true, nil
}
} else {
// Without timestamp: use format with most recent backup.
if v3UpdatedAt.After(ltxUpdatedAt) {
r.Logger().Debug("using v0.3.x restore (more recent backup)",
"v3_updated_at", v3UpdatedAt,
"ltx_updated_at", ltxUpdatedAt)
return true, nil
}
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Inspect the wrapped cause; verify read permissions on snapshot-level LTX prefixes.
- Retry the restore if transient.
- Check that lifecycle/retention rules are not deleting snapshot files before your PITR window (disable retention only when a cloud lifecycle policy owns cleanup).
- Restore latest without -timestamp to skip the snapshot filter.
Example fix
// before ltxSnapshot, err := r.findBestLTXSnapshotForTimestamp(ctx, timestamp) // after // ensure snapshot LTX files exist and are readable: // $ litestream ltx -level 4 <replica> // inspect levels // then retry the timestamped restore ltxSnapshot, err := r.findBestLTXSnapshotForTimestamp(ctx, timestamp)
Defensive patterns
Strategy: validation
Validate before calling
// Go: check snapshot-level files exist before a timestamped restore
infos, err := FindLTXFiles(ctx, client, SnapshotLevel, true, nil)
if err != nil || len(infos) == 0 {
return fmt.Errorf("no restorable LTX snapshots found")
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "find LTX snapshot") {
// verify snapshot prefixes readable; retry or restore latest
}
return err
} Prevention
- Ensure IAM allows reading snapshot-level LTX prefixes.
- Verify PITR window with `litestream ltx -level all` before relying on -timestamp.
- Keep retention windows aligned with your PITR requirements.
When it happens
Trigger: Restore -timestamp with both formats present and FindLTXFiles on SnapshotLevel fails: storage backend error while listing snapshot LTX files, or the filter callback's enumeration hitting a corrupt/unreadable object.
Common situations: Lifecycle policies deleting snapshot LTX files mid-restore; IAM missing read permission on snapshot prefixes; transient object-store 5xx errors.
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
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/e8720c287b0e2343.
Report an issue: GitHub.