benbjohnson/litestream · error
cannot build index: %w
Error message
cannot build index: %w
What it means
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.
Source
Thrown at vfs.go:1160
}
f.pos = pos
// Initialize write support TXID tracking
if f.writeEnabled {
f.expectedTXID = pos.TXID
f.pendingTXID = pos.TXID + 1
f.logger.Debug("write support enabled", "expectedTXID", f.expectedTXID, "pendingTXID", f.pendingTXID)
// Initialize write buffer file for durability (discards any existing buffer)
if err := f.initWriteBuffer(); err != nil {
return fmt.Errorf("initialize write buffer: %w", err)
}
}
// Build the page index so we can lookup individual pages.
if err := f.buildIndex(f.ctx, infos); err != nil {
f.logger.Error("cannot build index", "error", err)
return fmt.Errorf("cannot build index: %w", err)
}
// Start background hydration if enabled
if f.hydrationPath != "" {
if err := f.initHydration(infos); err != nil {
f.logger.Warn("hydration initialization failed, continuing without hydration", "error", err)
f.hydrationPath = ""
}
}
// Continuously monitor the replica client for new LTX files.
f.wg.Add(1)
go func() { defer f.wg.Done(); f.monitorReplicaClient(f.ctx) }()
// Start periodic sync goroutine if write support is enabled
if f.writeEnabled && f.syncInterval > 0 {
f.syncTicker = time.NewTicker(f.syncInterval)
f.syncStop = make(chan struct{})View on GitHub (pinned to 4ed7a308f6)
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
Example fix
// before
f, err := file.Open(ctx) // transient S3 timeout -> "cannot build index"
// after
var ferr *vfs.FileError
f, err := file.Open(ctx)
if errors.As(err, &ferr) || isTransient(err) {
time.Sleep(time.Second); f, err = file.Open(ctx) // retry
} Defensive patterns
Strategy: retry
Validate before calling
infos, err := client.LTXInfos(ctx)
for _, info := range infos { if err := verifyLTX(ctx, client, info); err != nil { return err } } Try / catch
if err := file.Open(ctx); err != nil {
if strings.Contains(err.Error(), "cannot build index") && isTransient(err) {
ctx2, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel(); return file.Open(ctx2)
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- detect page size: %w
- invalid replica, checksum mismatch
- open remote L0 file: %w
- no ltx file available to determine page size
- no snapshots available
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/81733c713a575cf9.
Report an issue: GitHub.