benbjohnson/litestream · error

close iterator: %w

Error message

close iterator: %w

What it means

At the end of ValidateLevel, the LTX file iterator must be closed to release backend resources (e.g. finalizing an S3 list operation or closing a local directory iterator). This error wraps itr.Close() failure, which usually reflects an underlying read error encountered while streaming the listing rather than a problem with the validation logic itself.

Source

Thrown at replica.go:1842

					PrevFile: prevInfo,
					CurrFile: info,
				})
			} else {
				errors = append(errors, ValidationError{
					Level:    level,
					Type:     "overlap",
					Message:  fmt.Sprintf("TXID overlap: prev.MaxTXID=%s, curr.MinTXID=%s", prevInfo.MaxTXID, info.MinTXID),
					PrevFile: prevInfo,
					CurrFile: info,
				})
			}
		}

		prevInfo = info
	}

	if err := itr.Close(); err != nil {
		return nil, fmt.Errorf("close iterator: %w", err)
	}

	return errors, nil
}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Retry ValidateLevel — transient listing/network failures typically resolve on retry
  2. Check network stability and provider status if using S3/GS/Azure
  3. If local, check the replica directory on disk for I/O errors (dmesg, SMART)
  4. Note that partial validation results are discarded when Close fails; re-run to get a full report

Example fix

// before: ignoring iterator close errors in your own code
itr.Close()
// after
if err := itr.Close(); err != nil {
    return fmt.Errorf("close iterator: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel() // ensure listing can complete before Close

Try / catch

errs, err := r.ValidateLevel(ctx, level)
if err != nil && strings.Contains(err.Error(), "close iterator") {
    // underlying listing I/O error: retry the whole validation
    errs, err = r.ValidateLevel(ctx, level)
}

Prevention

When it happens

Trigger: Calling ValidateLevel when the storage iterator's Close errors: connection dropped mid-listing for remote stores, checksum/IO error reading the local LTX directory listing, or the iterator already consumed/errored in a way the backend reports at close.

Common situations: Flaky network to S3/GCS aborting a paginated listing; local disk issues on the replica directory; hitting provider list-request limits during large listings.

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