benbjohnson/litestream · error

fetch l0 files: %w

Error message

fetch l0 files: %w

What it means

Wraps a failure from Replica.Client.LTXFiles when listing level-0 LTX files during L0 retention enforcement. Without a complete L0 listing the library cannot decide which files expired past L0Retention, so the retention cycle aborts.

Source

Thrown at db.go:3053

		info := itr.Item()
		if info.MaxTXID > maxL1TXID {
			maxL1TXID = info.MaxTXID
		}
	}
	if err := itr.Close(); err != nil {
		return fmt.Errorf("close l1 iterator: %w", err)
	}
	if maxL1TXID == 0 {
		internal.L0RetentionGaugeVec.WithLabelValues(dbName, "eligible").Set(0)
		internal.L0RetentionGaugeVec.WithLabelValues(dbName, "not_compacted").Set(0)
		internal.L0RetentionGaugeVec.WithLabelValues(dbName, "too_recent").Set(0)
		return nil
	}

	threshold := time.Now().Add(-db.L0Retention)
	itr, err = db.Replica.Client.LTXFiles(ctx, 0, 0, false)
	if err != nil {
		return fmt.Errorf("fetch l0 files: %w", err)
	}
	defer itr.Close()

	var (
		deleted           []*ltx.FileInfo
		lastInfo          *ltx.FileInfo
		processedAll      = true
		totalFiles        int
		notCompactedCount int
		tooRecentCount    int
	)
	for itr.Next() {
		info := itr.Item()
		lastInfo = info
		totalFiles++

		createdAt := info.CreatedAt
		if createdAt.IsZero() {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Verify storage credentials and endpoint reachability.
  2. Inspect the wrapped error (AccessDenied, Throttling, timeout) and fix the root cause.
  3. Retry the retention run with backoff; listing is read-only.
  4. For throttling, reduce listing concurrency or configure SDK retry settings.
  5. Validate the replica URL/path so listings target the correct prefix.

Example fix

// before
itr, err := db.Replica.Client.LTXFiles(ctx, 0, 0, false)
if err != nil { return fmt.Errorf("fetch l0 files: %w", err) }
// after (pre-flight)
if err := db.Replica.Client.Init(ctx); err != nil { return fmt.Errorf("init replica: %w", err) }
itr, err := db.Replica.Client.LTXFiles(ctx, 0, 0, false)
if err != nil { return fmt.Errorf("fetch l0 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, 0, 0, false)
if err != nil {
    if isTransient(err) { return retryWithBackoff(ctx) }
    return fmt.Errorf("fetch l0 files: %w", err)
}

Prevention

When it happens

Trigger: The L0 retention pass (db.go:3053) listing L0 files when the replica backend fails: network outage, expired credentials, wrong path prefix, or backend 5xx/throttling.

Common situations: High-churn databases with many L0 files triggering S3 listing throttling; credential rotation mid-run; proxy or VPC-endpoint failures.

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