{"record":{"id":"25321aedb2e2d858","repo":"benbjohnson/litestream","slug":"close-l1-iterator-w","errorCode":null,"errorMessage":"close l1 iterator: %w","messagePattern":"close l1 iterator: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compactor.go","lineNumber":361,"sourceCode":"\tif retention <= 0 {\n\t\treturn nil\n\t}\n\n\tc.logger.Debug(\"enforcing l0 retention\", \"retention\", retention)\n\n\titr, err := c.client.LTXFiles(ctx, 1, 0, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fetch l1 files: %w\", err)\n\t}\n\tvar maxL1TXID ltx.TXID\n\tfor itr.Next() {\n\t\tinfo := itr.Item()\n\t\tif info.MaxTXID > maxL1TXID {\n\t\t\tmaxL1TXID = info.MaxTXID\n\t\t}\n\t}\n\tif err := itr.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close l1 iterator: %w\", err)\n\t}\n\tif maxL1TXID == 0 {\n\t\treturn nil\n\t}\n\n\tthreshold := time.Now().Add(-retention)\n\titr, err = c.client.LTXFiles(ctx, 0, 0, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fetch l0 files: %w\", err)\n\t}\n\tdefer itr.Close()\n\n\tvar (\n\t\tdeleted      []*ltx.FileInfo\n\t\tlastInfo     *ltx.FileInfo\n\t\tprocessedAll = true\n\t)\n\tfor itr.Next() {","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/compactor.go#L343-L379","documentation":"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.","triggerScenarios":"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.","commonSituations":"Flaky network between Litestream and object storage; very large level-01 listings hitting provider timeouts; proxies/LBs cutting long-lived streams.","solutions":["Retry the EnforceL0Retention run after network recovery — it is safe to re-run","Check for proxies/firewalls terminating long connections; raise idle timeouts","Reduce listing pressure (fewer stale files) by fixing retention cadence","Investigate the wrapped provider error; treat as listing interruption, not data corruption"],"exampleFix":"// before: ignoring iterator close errors elsewhere\n_ = itr.Close()\n// after: always check close to catch truncated listings\nif err := itr.Close(); err != nil {\n    return fmt.Errorf(\"close l1 iterator: %w\", err)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := c.EnforceL0Retention(ctx, retention); err != nil {\n    if errors.Is(err, io.ErrUnexpectedEOF) || isNetError(err) {\n        // reschedule with backoff\n    }\n}","preventionTips":["Raise proxy/LB idle timeouts for long listings","Keep level-01 file counts bounded via retention","Run retention on a stable network path"],"tags":["storage","iterator","network","listing"],"backgroundTag":"file-list-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}