benbjohnson/litestream · error
list generations: %w
Error message
list generations: %w
What it means
RestoreV3 enumerates backup generations via client.GenerationsV3(ctx); if that remote listing fails the underlying error is wrapped as 'list generations: %w'. It is a transport/storage error while talking to the replica client backend (S3, file system, etc.), not an options problem. An empty (but successful) listing instead yields ErrNoSnapshots.
Source
Thrown at replica.go:1090
// Validate options.
if opt.OutputPath == "" {
return fmt.Errorf("output path required")
} else if opt.IntegrityCheck != IntegrityCheckNone && opt.IntegrityCheck != IntegrityCheckQuick && opt.IntegrityCheck != IntegrityCheckFull {
return fmt.Errorf("unsupported integrity check mode: %d", opt.IntegrityCheck)
}
// Ensure output path does not already exist.
if _, err := os.Stat(opt.OutputPath); err == nil {
return fmt.Errorf("cannot restore, output path already exists: %s", opt.OutputPath)
} else if !os.IsNotExist(err) {
return err
}
// Find all generations.
generations, err := client.GenerationsV3(ctx)
if err != nil {
return fmt.Errorf("list generations: %w", err)
}
if len(generations) == 0 {
return ErrNoSnapshots
}
// Collect all snapshots across all generations.
var allSnapshots []SnapshotInfoV3
for _, gen := range generations {
snapshots, err := client.SnapshotsV3(ctx, gen)
if err != nil {
return fmt.Errorf("list snapshots for generation %s: %w", gen, err)
}
allSnapshots = append(allSnapshots, snapshots...)
}
if len(allSnapshots) == 0 {
return ErrNoSnapshots
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Inspect the wrapped cause (%w) with errors.Unwrap/%v to see the storage error (auth, DNS, 4xx/5xx) and fix that backend issue
- Verify replica client config: bucket, endpoint, region, credentials, network reachability
- Retry the restore; generation listing is read-only and safe to repeat
- Run litestream ltx or list the bucket manually to confirm generations are visible
Example fix
// before
err := replica.Restore(ctx, opt) // opaque 'list generations: ...'
// after
if err := replica.Restore(ctx, opt); err != nil {
var ctxErr context.Error
log.Printf("restore failed, cause=%v", errors.Unwrap(err)) // surface backend error
_ = ctxErr
return err
} Defensive patterns
Strategy: retry
Validate before calling
// preflight: verify the backend is reachable and listable before restore
if _, err := client.GenerationsV3(ctx); err != nil {
return fmt.Errorf("replica backend unreachable: %w", err)
} Try / catch
if err := replica.Restore(ctx, opt); err != nil {
var ne net.Error
if errors.As(err, &ne) || strings.Contains(err.Error(), "list generations") {
return retryWithBackoff(ctx, 3, func() error { return replica.Restore(ctx, opt) })
}
return err
} Prevention
- Verify bucket/container name, region, endpoint, and credentials in the replica config before DR
- Run periodic restore drills to catch auth/network misconfigurations early
- Use exponential backoff for transient storage errors
- Confirm network/VPN/proxy access to the storage endpoint from the restore host
When it happens
Trigger: Calling Replica.Restore against a v0.3.x replica when the storage backend is unreachable, credentials are wrong, the bucket/container does not exist, or the backend returned a transient error while listing generation directories.
Common situations: Offline or misconfigured network during disaster recovery; expired S3 credentials or wrong region; pointing the client at the wrong bucket after a config change; S3 outage or throttling during list requests.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- list snapshots for generation %s: %w
- list WAL segments: %w
- download snapshot: %w
- list level %d ltx files: %w
- apply WAL segments: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/e85e2f0bf31e2531.
Report an issue: GitHub.