benbjohnson/litestream · error

fetch ltx files: %w

Error message

fetch ltx files: %w

What it means

Wraps a failure from Replica.Client.LTXFiles when listing remote LTX files at the snapshot level inside DB.EnforceSnapshotRetention. Retention enforcement cannot proceed without enumerating existing snapshot files, so the underlying storage error is propagated with context. It indicates a remote replica listing failure, not a local database problem.

Source

Thrown at db.go:2959

	if err != nil {
		return info, err
	}

	db.maxLTXFileInfos.Lock()
	db.maxLTXFileInfos.m[SnapshotLevel] = info
	db.maxLTXFileInfos.Unlock()

	return info, nil
}

// EnforceSnapshotRetention enforces retention of the snapshot level in the database by timestamp.
func (db *DB) EnforceSnapshotRetention(ctx context.Context, timestamp time.Time) (minSnapshotTXID ltx.TXID, err error) {
	db.Logger.Debug("enforcing snapshot retention", "timestamp", timestamp)

	// Normal operation - use fast timestamps
	itr, err := db.Replica.Client.LTXFiles(ctx, SnapshotLevel, 0, false)
	if err != nil {
		return 0, fmt.Errorf("fetch ltx files: %w", err)
	}
	defer itr.Close()

	var deleted []*ltx.FileInfo
	var snapshots []*ltx.FileInfo
	var lastInfo *ltx.FileInfo
	for itr.Next() {
		info := itr.Item()
		snapshots = append(snapshots, info)
		lastInfo = info

		// If this snapshot is before the retention timestamp, mark it for deletion.
		if info.CreatedAt.Before(timestamp) {
			deleted = append(deleted, info)
			continue
		}
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Verify replica connectivity and credentials (aws s3 ls / gsutil ls on the bucket path).
  2. Check litestream logs for the wrapped inner error (AccessDenied, NoSuchBucket) and fix the storage config.
  3. Retry after transient network issues; the listing is read-only and idempotent.
  4. In a custom ReplicaClient, ensure LTXFiles surfaces real errors instead of empty iterations.
  5. Confirm the replica URL scheme/host/path in the config are correct.

Example fix

// before
itr, err := db.Replica.Client.LTXFiles(ctx, SnapshotLevel, 0, false)
if err != nil { return 0, fmt.Errorf("fetch ltx files: %w", err) }
// after (caller-side guard)
if err := db.Replica.Client.Init(ctx); err != nil { return fmt.Errorf("init replica: %w", err) }
itr, err := db.Replica.Client.LTXFiles(ctx, SnapshotLevel, 0, false)
if err != nil { return 0, fmt.Errorf("fetch ltx files: %w", err) }
Defensive patterns

Strategy: retry

Validate before calling

if err := db.Replica.Client.Init(ctx); err != nil { return fmt.Errorf("replica init failed: %w", err) }

Try / catch

itr, err := db.Replica.Client.LTXFiles(ctx, SnapshotLevel, 0, false)
if err != nil {
    if isTransient(err) { return retryWithBackoff(ctx) }
    return fmt.Errorf("fetch ltx files: %w", err)
}

Prevention

When it happens

Trigger: Calling EnforceSnapshotRetention when the replica client's LTXFiles listing fails: network outage to S3/GS/Azure, expired credentials, wrong bucket/container, or a storage backend 5xx/throttle during snapshot-level listing.

Common situations: A scheduled retention run while the object store is unreachable or credentials were rotated; misconfigured replica URL pointing at a nonexistent bucket; S3 SlowDown throttling during bulk listing.

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/d6d510df3f06e246. Report an issue: GitHub.