{"record":{"id":"1edc34387462b06a","repo":"benbjohnson/litestream","slug":"read-ltx-header-w","errorCode":null,"errorMessage":"read ltx header: %w","messagePattern":"read ltx header: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":2799,"sourceCode":"\t}\n\treturn pageSize, nil\n}\n\nfunc detectPageSizeFromInfos(ctx context.Context, client ReplicaClient, infos []*ltx.FileInfo) (uint32, error) {\n\tvar lastErr error\n\tfor i := len(infos) - 1; i >= 0; i-- {\n\t\tpageSize, err := readPageSizeFromInfo(ctx, client, infos[i])\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t\tcontinue\n\t\t}\n\t\tif !isSupportedPageSize(pageSize) {\n\t\t\treturn 0, fmt.Errorf(\"unsupported page size: %d\", pageSize)\n\t\t}\n\t\treturn pageSize, nil\n\t}\n\tif lastErr != nil {\n\t\treturn 0, fmt.Errorf(\"read ltx header: %w\", lastErr)\n\t}\n\treturn 0, fmt.Errorf(\"no ltx file available to determine page size\")\n}\n\nfunc readPageSizeFromInfo(ctx context.Context, client ReplicaClient, info *ltx.FileInfo) (uint32, error) {\n\trc, err := client.OpenLTXFile(ctx, info.Level, info.MinTXID, info.MaxTXID, 0, ltx.HeaderSize)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"open ltx file: %w\", err)\n\t}\n\tdefer rc.Close()\n\tdec := ltx.NewDecoder(rc)\n\tif err := dec.DecodeHeader(); err != nil {\n\t\treturn 0, fmt.Errorf(\"decode ltx header: %w\", err)\n\t}\n\treturn dec.Header().PageSize, nil\n}\n\nfunc isSupportedPageSize(pageSize uint32) bool {","sourceCodeStart":2781,"sourceCodeEnd":2817,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L2781-L2817","documentation":"The page-size detection loop tried every candidate LTX file and each readPageSizeFromInfo call failed; the last underlying error is wrapped as 'read ltx header: %w'. If no files existed at all, a separate 'no ltx file available' error is returned.","triggerScenarios":"All candidate LTX files unreadable during page-size discovery: storage unreachable, credentials failing, zero-byte/truncated headers, or OpenLTXFile errors on every file.","commonSituations":"Freshly restored/empty replica bucket; network outage at VFS open time; IAM policy changes revoking read access; proxy stripping request ranges used to read only ltx.HeaderSize bytes.","solutions":["Read the wrapped error to identify why headers could not be read","Verify replica storage contains at least one readable LTX file (litestream ltx -level all)","Check credentials and network access to the storage endpoint","Confirm proxies/gateways support the range reads used for header-only fetches"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// confirm at least one readable LTX file exists before opening VFS\ninfos, err := listAllLTXInfos(ctx, client)\nif err != nil || len(infos) == 0 {\n    return fmt.Errorf(\"replica has no readable ltx files\")\n}","typeGuard":null,"tryCatchPattern":"if err := openVFS(); err != nil {\n    if strings.Contains(err.Error(), \"read ltx header\") {\n        // storage/network issue at open time\n        time.Sleep(retryDelay); return openVFS()\n    }\n    return err\n}","preventionTips":["Confirm replicas are populated before pointing readers at them","Check IAM read permissions on LTX prefixes","Ensure network paths support byte-range reads for header-only fetches"],"tags":["ltx","header","storage"],"backgroundTag":"file-read-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"}