{"record":{"id":"6d189206a6511cb1","repo":"benbjohnson/litestream","slug":"fetch-l1-files-w","errorCode":null,"errorMessage":"fetch l1 files: %w","messagePattern":"fetch l1 files: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compactor.go","lineNumber":351,"sourceCode":"\t\t}\n\t}\n\n\treturn nil\n}\n\n// EnforceL0Retention retains L0 files based on L1 compaction progress and time.\n// Files are only deleted if they have been compacted into L1 AND are older than retention.\n// This ensures contiguous L0 coverage for VFS reads.\nfunc (c *Compactor) EnforceL0Retention(ctx context.Context, retention time.Duration) error {\n\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 {","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/compactor.go#L333-L369","documentation":"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.","triggerScenarios":"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.","commonSituations":"Fresh replica with no L1 files yet plus a storage misconfiguration; credentials lacking list scope; endpoint misconfigured after migrating providers.","solutions":["Fix the replica client configuration/credentials so level-01 files can be listed","Confirm the replica actually has compacted L1 files (check compactor config for L1 interval)","Retry after storage backend recovery — L0 retention runs periodically","Read the wrapped provider error to distinguish auth vs. not-found vs. throttling"],"exampleFix":"// before: no L1 level configured so listing fails on a wrong prefix\n// config missing [[meta]]/L1 compaction interval\n// after: enable L1 compaction so level-01 files exist\n[compactor]\n  l1Interval = \"5m\"","handlingStrategy":"retry","validationCode":"// Confirm L1 files exist and are listable before L0 retention\nitr, err := client.LTXFiles(ctx, 1, 0, false)\nif err != nil {\n    return fmt.Errorf(\"l1 listing unavailable: %w\", err)\n}\nitr.Close()","typeGuard":null,"tryCatchPattern":"err := c.EnforceL0Retention(ctx, retention)\nif err != nil {\n    log.Warn(\"l0 retention deferred\", \"err\", err) // retried next cycle\n}","preventionTips":["Enable L1 compaction so a watermark exists","Validate credentials include the level-01 prefix scope","Treat as transient; the monitor loop retries"],"tags":["storage","listing","l0-retention","network"],"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-14T00:17:10.932Z"}