benbjohnson/litestream · error

fetch l1 files: %w

Error message

fetch l1 files: %w

What it means

EnforceL0Retention first lists level-1 (L1) files to find the maximum L1 TXID, which acts as the safe deletion boundary for L0 files. If listing L1 files fails, the error is wrapped as 'fetch l1 files: %w'. Retention cannot proceed without knowing the L1 watermark.

Source

Thrown at compactor.go:351

		}
	}

	return nil
}

// EnforceL0Retention retains L0 files based on L1 compaction progress and time.
// Files are only deleted if they have been compacted into L1 AND are older than retention.
// This ensures contiguous L0 coverage for VFS reads.
func (c *Compactor) EnforceL0Retention(ctx context.Context, retention time.Duration) error {
	if retention <= 0 {
		return nil
	}

	c.logger.Debug("enforcing l0 retention", "retention", retention)

	itr, err := c.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 {
		return nil
	}

	threshold := time.Now().Add(-retention)
	itr, err = c.client.LTXFiles(ctx, 0, 0, false)
	if err != nil {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Fix the replica client configuration/credentials so level-01 files can be listed
  2. Confirm the replica actually has compacted L1 files (check compactor config for L1 interval)
  3. Retry after storage backend recovery — L0 retention runs periodically
  4. Read the wrapped provider error to distinguish auth vs. not-found vs. throttling

Example fix

// before: no L1 level configured so listing fails on a wrong prefix
// config missing [[meta]]/L1 compaction interval
// after: enable L1 compaction so level-01 files exist
[compactor]
  l1Interval = "5m"
Defensive patterns

Strategy: retry

Validate before calling

// Confirm L1 files exist and are listable before L0 retention
itr, err := client.LTXFiles(ctx, 1, 0, false)
if err != nil {
    return fmt.Errorf("l1 listing unavailable: %w", err)
}
itr.Close()

Try / catch

err := c.EnforceL0Retention(ctx, retention)
if err != nil {
    log.Warn("l0 retention deferred", "err", err) // retried next cycle
}

Prevention

When it happens

Trigger: EnforceL0Retention (or monitorL0Retention) runs while c.client.LTXFiles(ctx, 1, 0, false) fails — auth failure, unreachable storage, missing level-01/ prefix, or provider list error.

Common situations: Fresh replica with no L1 files yet plus a storage misconfiguration; credentials lacking list scope; endpoint misconfigured after migrating providers.

Related errors


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