benbjohnson/litestream · error
ltx files: %w
Error message
ltx files: %w
What it means
Wraps failure fetching LTX files for a level in VFSFile.pollLevel, which polls the replica for new files to update the virtual file's index. Fires when the replica client's LTXFiles call errors during a poll cycle, so level updates cannot proceed.
Source
Thrown at vfs.go:2722
f.maxTXID1 = maxTXID1
f.logger.Debug("txid updated", "txid", f.pos.TXID.String(), "maxTXID1", f.maxTXID1.String())
// Apply updates to hydrated file if hydration is complete
if f.hydrator != nil && f.hydrator.Complete() && len(combined) > 0 {
if err := f.hydrator.ApplyUpdates(f.ctx, combined); err != nil {
f.logger.Error("failed to apply updates to hydrated file", "error", err)
}
}
return nil
}
// pollLevel fetches LTX files for a specific level and returns the highest TXID seen,
// any index updates, the latest commit value, and if the index should be replaced.
func (f *VFSFile) pollLevel(ctx context.Context, level int, prevMaxTXID ltx.TXID, baseCommit uint32) (ltx.TXID, map[uint32]ltx.PageIndexElem, uint32, bool, error) {
itr, err := f.client.LTXFiles(ctx, level, prevMaxTXID+1, false)
if err != nil {
return prevMaxTXID, nil, baseCommit, false, fmt.Errorf("ltx files: %w", err)
}
defer func() { _ = itr.Close() }()
index := make(map[uint32]ltx.PageIndexElem)
maxTXID := prevMaxTXID
lastCommit := baseCommit
newCommit := baseCommit
replaceIndex := false
for itr.Next() {
info := itr.Item()
f.mu.Lock()
isNextTXID := info.MinTXID == maxTXID+1
f.mu.Unlock()
if !isNextTXID {
if level == 0 && info.MinTXID > maxTXID+1 {
f.logger.Warn("ltx gap detected at L0, deferring to higher levels", "expected", maxTXID+1, "next", info.MinTXID)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Read the wrapped error for the concrete client failure
- Validate credentials and bucket configuration for the replica client
- Check for storage provider throttling and add backoff/retry at the client level
- Run `litestream reset` if local replicated state is corrupted after repeated failures
Defensive patterns
Strategy: retry
Validate before calling
// verify list access before opening VFS
itr, err := replicaClient.LTXFiles(context.Background(), 0, 1, false)
if err != nil { return fmt.Errorf("cannot list replica: %w", err) }
itr.Close() Try / catch
itr, err := client.LTXFiles(ctx, level, minTXID, false)
if err != nil {
if isRetryablePageError(err) { return retryAfterBackoff() }
return fmt.Errorf("ltx files: %w", err)
} Prevention
- Validate replica client config at startup
- Set generous timeouts for object storage clients
- Handle provider 5xx/SlowDown with exponential backoff
When it happens
Trigger: Any failure from the ReplicaClient's LTXFiles listing API: network errors, HTTP error responses from S3/GCS/Azure, invalid credentials, or unsupported client implementations.
Common situations: Expired cloud credentials mid-run; region/endpoint misconfiguration; object storage throttling (5xx / SlowDown); VPC without egress to the storage endpoint.
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
- fetch ltx files: %w
- open ltx file: %w
- no snapshots available
- abs: cannot delete ltx file %q: %w
- abs: cannot list blobs: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/7efc63331f8968ea.
Report an issue: GitHub.