benbjohnson/litestream · error

fetch l1 files: %w

Error message

fetch l1 files: %w

What it means

Wraps a failure from Replica.Client.LTXFiles when listing level-1 (L1) compacted files to determine the highest compacted TXID during L0 retention processing. The listing must succeed to know whether L0 files can be safely removed, so the error aborts the operation.

Source

Thrown at db.go:3031

	return minSnapshotTXID, nil
}

// EnforceL0RetentionByTime retains L0 files until they have been compacted into
// L1 and have existed for at least L0Retention.
func (db *DB) EnforceL0RetentionByTime(ctx context.Context) error {
	if db.L0Retention <= 0 {
		return nil
	}

	db.Logger.Debug("starting l0 retention enforcement", "retention", db.L0Retention)

	dbName := filepath.Base(db.Path())

	// Determine the highest TXID that has been compacted into L1.
	itr, err := db.Replica.Client.LTXFiles(ctx, 1, 0, false)
	if err != nil {
		return fmt.Errorf("fetch l1 files: %w", err)
	}
	var maxL1TXID ltx.TXID
	for itr.Next() {
		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
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Test bucket access with the provider CLI using the same credentials.
  2. Read the wrapped inner error to distinguish auth vs network vs not-found.
  3. Retry after connectivity is restored; the listing is read-only.
  4. Verify replica config (endpoint, region, bucket) especially for S3-compatible providers.

Example fix

// caller-side retry around the retention pass
if err := enforceL0Retention(ctx, db); err != nil && isTransient(err) {
    time.Sleep(backoff)
    err = enforceL0Retention(ctx, db)
}
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, 1, 0, false)
if err != nil {
    if isTransient(err) { return retryWithBackoff(ctx) }
    return fmt.Errorf("fetch l1 files: %w", err)
}

Prevention

When it happens

Trigger: Running L0 retention enforcement when the remote L1 listing fails: storage outage, bad credentials, DNS failure, or a misconfigured replica endpoint (db.go:3031).

Common situations: Periodic compaction/retention job running while the object store is down; expired IAM credentials; unreachable S3/GS endpoint from a VPC.

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