benbjohnson/litestream · error

close l1 iterator: %w

Error message

close l1 iterator: %w

What it means

After enumerating L1 files, EnforceL0Retention closes the iterator; a non-nil error from itr.Close() is wrapped as 'close l1 iterator: %w'. Many storage backends stream listings, so close-time errors surface truncation or network drops that occurred mid-listing.

Source

Thrown at compactor.go:361

	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 {
		return fmt.Errorf("fetch l0 files: %w", err)
	}
	defer itr.Close()

	var (
		deleted      []*ltx.FileInfo
		lastInfo     *ltx.FileInfo
		processedAll = true
	)
	for itr.Next() {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Retry the EnforceL0Retention run after network recovery — it is safe to re-run
  2. Check for proxies/firewalls terminating long connections; raise idle timeouts
  3. Reduce listing pressure (fewer stale files) by fixing retention cadence
  4. Investigate the wrapped provider error; treat as listing interruption, not data corruption

Example fix

// before: ignoring iterator close errors elsewhere
_ = itr.Close()
// after: always check close to catch truncated listings
if err := itr.Close(); err != nil {
    return fmt.Errorf("close l1 iterator: %w", err)
}
Defensive patterns

Strategy: retry

Try / catch

if err := c.EnforceL0Retention(ctx, retention); err != nil {
    if errors.Is(err, io.ErrUnexpectedEOF) || isNetError(err) {
        // reschedule with backoff
    }
}

Prevention

When it happens

Trigger: itr.Close() returning an error because the underlying listing stream failed partway — dropped connection, provider closed the stream early, or pagination request failed while draining results.

Common situations: Flaky network between Litestream and object storage; very large level-01 listings hitting provider timeouts; proxies/LBs cutting long-lived streams.

Related errors


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