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

  1. Read the wrapped error for the concrete client failure
  2. Validate credentials and bucket configuration for the replica client
  3. Check for storage provider throttling and add backoff/retry at the client level
  4. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/7efc63331f8968ea. Report an issue: GitHub.