benbjohnson/litestream · error
fetch ltx files: %w
Error message
fetch ltx files: %w
What it means
Replica.ValidateLevel lists LTX files at a compaction level by calling r.Client.LTXFiles(ctx, level, 0, false) to obtain a file iterator. This error wraps a failure to open/enumerate the remote (or local) LTX file listing from the replica client, so validation cannot proceed and no ValidationError list is produced.
Source
Thrown at replica.go:1787
return txid, nil
}
// ValidationError represents a single validation issue.
type ValidationError struct {
Level int // compaction level
Type string // "gap", "overlap", or "unsorted"
Message string // human-readable description
PrevFile *ltx.FileInfo // previous file
CurrFile *ltx.FileInfo // current file that caused error
}
// ValidateLevel checks LTX files at the given level are sorted and contiguous.
// Returns a slice of validation errors (empty if valid).
func (r *Replica) ValidateLevel(ctx context.Context, level int) ([]ValidationError, error) {
itr, err := r.Client.LTXFiles(ctx, level, 0, false)
if err != nil {
return nil, fmt.Errorf("fetch ltx files: %w", err)
}
defer itr.Close()
var errors []ValidationError
var prevInfo *ltx.FileInfo
for itr.Next() {
info := itr.Item()
// Skip first file - nothing to compare against
if prevInfo == nil {
prevInfo = info
continue
}
// Check for sort order: curr.MinTXID should be >= prev.MinTXID
if info.MinTXID < prevInfo.MinTXID {
errors = append(errors, ValidationError{View on GitHub (pinned to 4ed7a308f6)
Solutions
- Run 'litestream replicas' or check the replica URL to confirm storage configuration (bucket, prefix, region, endpoint)
- Verify cloud credentials/permissions (s3:Get/List on the bucket prefix) and that they are not expired
- Test network connectivity to the storage endpoint from the host running validation
- Check that the compaction level passed to ValidateLevel is valid (0–9) and that files exist at that level
Example fix
// before
itr, err := client.LTXFiles(ctx, level, 0, false)
// after: verify connectivity and creds before validating
if err := clientHelmetCheck(ctx, r.Client); err != nil { return err }
itr, err := r.Client.LTXFiles(ctx, level, 0, false)
if err != nil { return fmt.Errorf("fetch ltx files at level %d: %w", level, err) } Defensive patterns
Strategy: retry
Validate before calling
// Validate replica config before calling ValidateLevel
if r.Client == nil { return fmt.Errorf("replica client not initialized") }
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel() Type guard
func clientReady(r *Replica) bool { return r != nil && r.Client != nil } Try / catch
errs, err := r.ValidateLevel(ctx, level)
if err != nil {
// transient storage/network failures: retry with backoff
errs, err = retryWithBackoff(3, func() ([]ValidationError, error) {
return r.ValidateLevel(ctx, level)
})
} Prevention
- Validate storage config (bucket, region, endpoint, credentials) before validation runs
- Use short timeouts and bounded retries for listing calls
- Refresh cloud credentials/roles before long maintenance windows
- Run 'litestream replicas' first as a cheap connectivity check
When it happens
Trigger: Calling ValidateLevel (or validation commands that use it) when the storage backend's LTXFiles listing fails: S3/GS/Azure credentials invalid or expired, bucket/container missing, network unreachable, or the storage client was not initialized for that level.
Common situations: Wrong bucket name or region in litestream.yml; expired cloud credentials (IAM role rotated, token expired); firewall/egress blocking the storage endpoint; s3 replica with a path that no longer exists after a provider migration.
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
- close iterator: %w
- abs: cannot delete ltx file %q: %w
- abs: cannot list blobs: %w
- abs: cannot delete blob %q: %w
- close iterator: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/38cfcfc14998145f.
Report an issue: GitHub.