benbjohnson/litestream · error
find v0.3.x snapshot: %w
Error message
find v0.3.x snapshot: %w
What it means
Wraps an error from findBestV3SnapshotForTimestamp when comparing v0.3.x and LTX snapshots against a requested restore timestamp. Litestream could not enumerate v0.3.x snapshots, so it cannot decide which format holds the best snapshot before the timestamp.
Source
Thrown at replica.go:1429
}
// If no v0.3.x backups exist, use LTX.
if v3UpdatedAt.IsZero() {
return false, nil
}
// 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,View on GitHub (pinned to 4ed7a308f6)
Solutions
- Resolve the underlying SnapshotsV3 failure (credentials, network, generation presence).
- Retry the timestamp restore; throttled listings usually succeed on retry.
- Restore without -timestamp (latest) to bypass the timestamp comparison path.
- Reduce generation count/fragmentation by re-replicating into a clean generation.
Example fix
// before $ litestream restore -timestamp 2024-01-01T00:00:00Z db // error: find v0.3.x snapshot: ... // after // fix credentials, then retry; or restore latest: $ litestream restore db
Defensive patterns
Strategy: retry
Try / catch
if err := restoreWithTimestamp(ts); err != nil {
if strings.Contains(err.Error(), "find v0.3.x snapshot") {
// fall back to latest restore or fix backend listing then retry
return retryOrFallback(err)
}
return err
} Prevention
- Test timestamp restores during DR drills, not during a real outage.
- Watch for provider rate limits when many generations must be listed.
- Consolidate fragmented generations via re-replication.
When it happens
Trigger: Restore with a -timestamp option where both v0.3.x and LTX backups exist and SnapshotsV3 fails for any generation (same cause family as error 460).
Common situations: Timestamp-based PITR against a migrated replica; stale credentials; backend throttling during listing of many generations.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- find LTX snapshot: %w
- list v0.3.x snapshots for generation %s: %w
- get v0.3.x time bounds: %w
- find LTX snapshots: %w
- cannot specify both TXID & timestamp to restore
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/6bc122e717b2a2c4.
Report an issue: GitHub.