{"record":{"id":"37b7a16b4f0de7c0","repo":"benbjohnson/litestream","slug":"fetch-header-w","errorCode":null,"errorMessage":"fetch header: %w","messagePattern":"fetch header: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":1355,"sourceCode":"\tindex := make(map[uint32]ltx.PageIndexElem)\n\tvar commit uint32\n\tfor _, info := range infos {\n\t\tf.logger.Debug(\"opening page index\", \"level\", info.Level, \"min\", info.MinTXID, \"max\", info.MaxTXID)\n\n\t\t// Read page index.\n\t\tidx, err := FetchPageIndex(ctx, f.client, info)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"fetch page index: %w\", err)\n\t\t}\n\n\t\t// Replace pages in overall index with new pages.\n\t\tfor k, v := range idx {\n\t\t\tf.logger.Debug(\"adding page index\", \"page\", k, \"elem\", v)\n\t\t\tindex[k] = v\n\t\t}\n\t\thdr, err := FetchLTXHeader(ctx, f.client, info)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"fetch header: %w\", err)\n\t\t}\n\t\tcommit = hdr.Commit\n\t}\n\n\tf.mu.Lock()\n\tf.commit = commit\n\tf.mu.Unlock()\n\n\treturn index, nil\n}\n\n// buildIndex constructs a lookup of pgno to LTX file offsets (legacy wrapper).\nfunc (f *VFSFile) buildIndex(ctx context.Context, infos []*ltx.FileInfo) error {\n\treturn f.rebuildIndex(ctx, infos, nil)\n}\n\n// initHydration starts the background hydration process.\nfunc (f *VFSFile) initHydration(infos []*ltx.FileInfo) error {","sourceCodeStart":1337,"sourceCodeEnd":1373,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L1337-L1373","documentation":"After merging page indexes in rebuildIndex, the VFS calls FetchLTXHeader for the latest LTX file to obtain the commit header (page size, commit count). A failure downloading or decoding that header is wrapped as \"fetch header: %w\". Without a valid commit header the rebuilt index cannot be installed.","triggerScenarios":"ResetTime/time-travel rebuild reaching FetchLTXHeader when the LTX object is missing, truncated, corrupt, or the replica client returns a transport error; also when the latest LTX file was replaced/deleted between planning and fetch.","commonSituations":"Object-store outages or throttling (S3 503 SlowDown); truncated uploads from a killed litestream process; LTX format/version mismatch between client and stored files; credentials revoked mid-operation.","solutions":["Inspect the wrapped error to identify transport vs. format failure.","Retry the rebuild; transient storage errors frequently clear.","Validate the newest LTX with `litestream ltx -level all`; re-replicate if corrupt.","Ensure the litestream version writing LTX files matches the version reading them."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := file.ResetTime(ctx); err != nil {\n    var se *storeError\n    if errors.As(err, &se) && isTransient(se.Unwrap()) {\n        time.Sleep(backoff)\n        err = file.ResetTime(ctx)\n    }\n}","preventionTips":["Keep litestream writer and VFS reader versions compatible (LTX format).","Enable client retries/throttling handling for the object store (S3 503, GCS 429).","Validate the newest LTX with `litestream ltx` after replication failures or killed processes."],"tags":["network","storage","ltx-header","litestream"],"backgroundTag":"http-request-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"}