{"record":{"id":"81733c713a575cf9","repo":"benbjohnson/litestream","slug":"cannot-build-index-w","errorCode":null,"errorMessage":"cannot build index: %w","messagePattern":"cannot build index: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":1160,"sourceCode":"\t}\n\tf.pos = pos\n\n\t// Initialize write support TXID tracking\n\tif f.writeEnabled {\n\t\tf.expectedTXID = pos.TXID\n\t\tf.pendingTXID = pos.TXID + 1\n\t\tf.logger.Debug(\"write support enabled\", \"expectedTXID\", f.expectedTXID, \"pendingTXID\", f.pendingTXID)\n\n\t\t// Initialize write buffer file for durability (discards any existing buffer)\n\t\tif err := f.initWriteBuffer(); err != nil {\n\t\t\treturn fmt.Errorf(\"initialize write buffer: %w\", err)\n\t\t}\n\t}\n\n\t// Build the page index so we can lookup individual pages.\n\tif err := f.buildIndex(f.ctx, infos); err != nil {\n\t\tf.logger.Error(\"cannot build index\", \"error\", err)\n\t\treturn fmt.Errorf(\"cannot build index: %w\", err)\n\t}\n\n\t// Start background hydration if enabled\n\tif f.hydrationPath != \"\" {\n\t\tif err := f.initHydration(infos); err != nil {\n\t\t\tf.logger.Warn(\"hydration initialization failed, continuing without hydration\", \"error\", err)\n\t\t\tf.hydrationPath = \"\"\n\t\t}\n\t}\n\n\t// Continuously monitor the replica client for new LTX files.\n\tf.wg.Add(1)\n\tgo func() { defer f.wg.Done(); f.monitorReplicaClient(f.ctx) }()\n\n\t// Start periodic sync goroutine if write support is enabled\n\tif f.writeEnabled && f.syncInterval > 0 {\n\t\tf.syncTicker = time.NewTicker(f.syncInterval)\n\t\tf.syncStop = make(chan struct{})","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L1142-L1178","documentation":"Raised during VFSFile.Open when buildIndex fails to construct the page index from the replica's LTX file infos. The index maps page numbers to their location in LTX files; without it the VFS cannot serve any page reads. The underlying error is also logged at Error level with context.","triggerScenarios":"buildIndex fails while reading LTX page indexes from the replica client: corrupt/truncated LTX file, network error to the storage backend, page-size mismatch between infos, or context cancellation during a slow listing/read.","commonSituations":"Corrupt LTX files in the bucket (interrupted upload); S3/replica connectivity or IAM issues mid-open; opening a replica that mixes generations with different page sizes; short client timeouts on large replicas.","solutions":["Validate replica LTX files (litestream ltx -level all) and re-replicate if corrupt","Check replica storage connectivity/credentials and retry","Run litestream reset for the database if local LTX state is inconsistent","Increase client timeouts / retry so large index builds aren't cancelled"],"exampleFix":"// before\nf, err := file.Open(ctx) // transient S3 timeout -> \"cannot build index\"\n// after\nvar ferr *vfs.FileError\nf, err := file.Open(ctx)\nif errors.As(err, &ferr) || isTransient(err) {\n    time.Sleep(time.Second); f, err = file.Open(ctx) // retry\n}","handlingStrategy":"retry","validationCode":"infos, err := client.LTXInfos(ctx)\nfor _, info := range infos { if err := verifyLTX(ctx, client, info); err != nil { return err } }","typeGuard":null,"tryCatchPattern":"if err := file.Open(ctx); err != nil {\n    if strings.Contains(err.Error(), \"cannot build index\") && isTransient(err) {\n        ctx2, cancel := context.WithTimeout(context.Background(), 60*time.Second)\n        defer cancel(); return file.Open(ctx2)\n    }\n    return err\n}","preventionTips":["Run litestream ltx to validate replica files periodically","Use generous timeouts; index builds hit the replica repeatedly","Use litestream reset if local LTX state is corrupt","Avoid opening while replication uploads are in flight for the same generation"],"tags":["index","ltx","replica","open"],"backgroundTag":"checksum-mismatch","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"}