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
- Retry ValidateLevel — transient listing/network failures typically resolve on retry
- Check network stability and provider status if using S3/GS/Azure
- If local, check the replica directory on disk for I/O errors (dmesg, SMART)
- 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
- Ensure stable network to the storage backend during validation
- Avoid aborting validation mid-listing (context cancellation)
- Keep replica listings small via retention/compaction to reduce list size
- Check provider rate limits if validating many levels in a loop
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
- close l1 iterator: %w
- close level %d ltx iterator: %w
- fetch ltx files: %w
- abs: cannot delete ltx file %q: %w
- abs: cannot list blobs: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/e4bbb0da044208ce.
Report an issue: GitHub.