{"record":{"id":"133e0067196675c8","repo":"benbjohnson/litestream","slug":"find-ltx-snapshots-w","errorCode":null,"errorMessage":"find LTX snapshots: %w","messagePattern":"find LTX snapshots: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":1503,"sourceCode":"\t\t\t}\n\t\t\tif updatedAt.IsZero() || seg.CreatedAt.After(updatedAt) {\n\t\t\t\tupdatedAt = seg.CreatedAt\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createdAt, updatedAt, nil\n}\n\n// findBestLTXSnapshotForTimestamp returns the best LTX snapshot for the given timestamp.\n// Returns nil if no suitable snapshot exists.\nfunc (r *Replica) findBestLTXSnapshotForTimestamp(ctx context.Context, timestamp time.Time) (*ltx.FileInfo, error) {\n\t// Find snapshots at the snapshot level that are before the timestamp.\n\tsnapshots, err := FindLTXFiles(ctx, r.Client, SnapshotLevel, true, func(info *ltx.FileInfo) (bool, error) {\n\t\treturn info.CreatedAt.Before(timestamp), nil\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"find LTX snapshots: %w\", err)\n\t}\n\tif len(snapshots) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Return the latest snapshot before the timestamp (last in the sorted list).\n\treturn snapshots[len(snapshots)-1], nil\n}\n\n// CalcRestorePlan returns a list of storage paths to restore a snapshot at the given TXID.\nfunc CalcRestorePlan(ctx context.Context, client ReplicaClient, txID ltx.TXID, timestamp time.Time, logger *slog.Logger) ([]*ltx.FileInfo, error) {\n\tif txID != 0 && !timestamp.IsZero() {\n\t\treturn nil, fmt.Errorf(\"cannot specify both TXID & timestamp to restore\")\n\t}\n\n\tvar infos ltx.FileInfoSlice\n\tlogger = logger.With(\"target\", txID)\n","sourceCodeStart":1485,"sourceCodeEnd":1521,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L1485-L1521","documentation":"Wraps an error from FindLTXFiles when collecting snapshot-level LTX files before a target timestamp. It means the snapshot listing itself failed (as opposed to returning zero matches). The best candidate snapshot could not be determined.","triggerScenarios":"Restore -> shouldUseV3Restore -> findBestLTXSnapshotForTimestamp: the replica client errors while listing snapshot-level files (network, auth, corrupt listing) rather than simply finding none.","commonSituations":"Object storage outages during DR drills; expired session tokens; misconfigured endpoint URLs after provider migration.","solutions":["Read the wrapped cause and fix the backend listing failure (auth, endpoint, network).","Retry; use litestream ltx -level all to verify snapshot files are listable.","Confirm the replica path in config matches the actual bucket layout.","As a fallback, restore latest without a timestamp."],"exampleFix":"// before\nsnapshots, err := FindLTXFiles(ctx, r.Client, SnapshotLevel, true, filter)\nif err != nil {\n    return nil, fmt.Errorf(\"find LTX snapshots: %w\", err)\n}\n// after\n// verify listing works:\n// $ litestream ltx -level 4 -level 5 <db-path>\n// then re-run restore\nsnapshots, err := FindLTXFiles(ctx, r.Client, SnapshotLevel, true, filter)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"snapshots, err := findBestLTXSnapshotForTimestamp(ctx, ts)\nif err != nil {\n    // wrapped backend listing error: fix endpoint/auth, then retry with backoff\n    return fmt.Errorf(\"snapshot listing failed: %w\", err)\n}\nif snapshots == nil {\n    // zero matches is NOT an error: fall back to another format\n}","preventionTips":["Validate storage endpoint URLs after provider migrations.","Refresh session tokens before long DR procedures.","Distinguish empty-result (nil, nil) from listing errors in custom tooling."],"tags":["restore","ltx","snapshot-selection","storage-backend"],"backgroundTag":"api-request-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}