{"record":{"id":"15aac93623140581","repo":"benbjohnson/litestream","slug":"fetch-ltx-files-w","errorCode":null,"errorMessage":"fetch ltx files: %w","messagePattern":"fetch ltx files: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compactor.go","lineNumber":244,"sourceCode":"\t}\n\n\tif err := itr.Close(); err != nil {\n\t\treturn fmt.Errorf(\"close iterator: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// EnforceSnapshotRetention enforces retention of snapshot level files by timestamp.\n// Files older than the retention duration are deleted (except the newest is always kept).\n// Returns the minimum snapshot TXID still retained (useful for cascading retention to lower levels).\nfunc (c *Compactor) EnforceSnapshotRetention(ctx context.Context, retention time.Duration) (ltx.TXID, error) {\n\ttimestamp := time.Now().Add(-retention)\n\tc.logger.Debug(\"enforcing snapshot retention\", \"timestamp\", timestamp)\n\n\titr, err := c.client.LTXFiles(ctx, SnapshotLevel, 0, false)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"fetch ltx files: %w\", err)\n\t}\n\tdefer itr.Close()\n\n\tvar deleted []*ltx.FileInfo\n\tvar lastInfo *ltx.FileInfo\n\tvar minSnapshotTXID ltx.TXID\n\n\tfor itr.Next() {\n\t\tinfo := itr.Item()\n\t\tlastInfo = info\n\n\t\tif info.CreatedAt.Before(timestamp) {\n\t\t\tdeleted = append(deleted, info)\n\t\t\tcontinue\n\t\t}\n\n\t\tif minSnapshotTXID == 0 || info.MaxTXID < minSnapshotTXID {\n\t\t\tminSnapshotTXID = info.MaxTXID","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/compactor.go#L226-L262","documentation":"EnforceSnapshotRetention could not open the LTX file iterator for the snapshot level (SnapshotLevel) because c.client.LTXFiles returned an error; the retention sweep aborts with 'fetch ltx files: <err>'. No snapshot files are evaluated or deleted when this fires — it's a listing failure at the storage layer, before any cleanup happens.","triggerScenarios":"Called by monitorSnapshots when enforcing snapshot retention; the storage client fails to list snapshot-level files — missing bucket/prefix, revoked credentials, network failure, context canceled, or the ReplicaClient not supporting listing for that level.","commonSituations":"S3 credentials expired or IAM policy lacking ListObjectsV2; bucket/prefix misconfigured in the replica config; storage outage; local file replica directory removed out-of-band; retention monitor running against a replica client that can't reach the remote.","solutions":["Inspect the wrapped error — auth vs network vs missing bucket/prefix","Verify replica storage config (endpoint, bucket, prefix, credentials) with `litestream ltx -level <n>` or a direct storage listing","Re-authenticate / fix IAM permissions so listing snapshot-level files is allowed","Check network/VPN to the storage endpoint; retry after outage","Ensure the local replica directory wasn't deleted; run `litestream reset <db>` if local LTX state is corrupt"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-flight listing before relying on retention:\nitr, err := client.LTXFiles(ctx, litestream.SnapshotLevel, 0, false)\nif err != nil { log.Fatalf(\"storage listing unavailable: %v\", err) }\nitr.Close()","typeGuard":null,"tryCatchPattern":"if err := compactor.EnforceSnapshotRetention(ctx, retention); err != nil {\n    if strings.Contains(err.Error(), \"fetch ltx files\") {\n        // check credentials/bucket, then retry with backoff\n    }\n}","preventionTips":["Validate replica credentials and bucket/prefix in config before enabling retention","Grant the storage principal list permissions (e.g. s3:ListBucket)","Alert on storage outages so retention failures are noticed","Don't delete local replica directories out-of-band; use litestream reset instead"],"tags":["storage","ltx","retention","network"],"backgroundTag":"file-not-found","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"}