benbjohnson/litestream · error
no ltx file available to determine page size
Error message
no ltx file available to determine page size
What it means
Litestream's VFS page-size detection reads the header of the newest LTX file in the replica to learn the database's page size. When the replica contains no LTX files at all (the file listing comes back empty), it cannot determine a page size and returns this error. It indicates the remote has no backup data to read from, not a malformed file.
Source
Thrown at vfs.go:2801
}
func detectPageSizeFromInfos(ctx context.Context, client ReplicaClient, infos []*ltx.FileInfo) (uint32, error) {
var lastErr error
for i := len(infos) - 1; i >= 0; i-- {
pageSize, err := readPageSizeFromInfo(ctx, client, infos[i])
if err != nil {
lastErr = err
continue
}
if !isSupportedPageSize(pageSize) {
return 0, fmt.Errorf("unsupported page size: %d", pageSize)
}
return pageSize, nil
}
if lastErr != nil {
return 0, fmt.Errorf("read ltx header: %w", lastErr)
}
return 0, fmt.Errorf("no ltx file available to determine page size")
}
func readPageSizeFromInfo(ctx context.Context, client ReplicaClient, info *ltx.FileInfo) (uint32, error) {
rc, err := client.OpenLTXFile(ctx, info.Level, info.MinTXID, info.MaxTXID, 0, ltx.HeaderSize)
if err != nil {
return 0, fmt.Errorf("open ltx file: %w", err)
}
defer rc.Close()
dec := ltx.NewDecoder(rc)
if err := dec.DecodeHeader(); err != nil {
return 0, fmt.Errorf("decode ltx header: %w", err)
}
return dec.Header().PageSize, nil
}
func isSupportedPageSize(pageSize uint32) bool {
switch pageSize {
case 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536:View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify the replica actually has LTX objects (litestream ltx -level all or list the bucket prefix)
- Run a litestream replicate sync to populate the remote before opening via VFS
- Check the config: correct bucket, path/prefix and database path — a wrong prefix lists zero files
- If local LTX state is corrupted, use litestream reset and re-replicate
Example fix
// before: opening VFS against an empty replica prefix client, _ := litestreamvfs.Open(ctx, "s3://my-bucket/wrong-prefix/db") // after: point at the prefix the replicator writes to and confirm files exist client, _ := litestreamvfs.Open(ctx, "s3://my-bucket/litestream/db")
Defensive patterns
Strategy: validation
Validate before calling
infos, err := client.ListLTXFiles(ctx)
if err != nil { return err }
if len(infos) == 0 { return fmt.Errorf("replica has no ltx files; run replicate first") } Try / catch
if err := openVFS(ctx); err != nil {
if strings.Contains(err.Error(), "no ltx file available") {
return syncReplicaFirst(ctx)
}
return err
} Prevention
- Run a successful replicate sync before any VFS/restore open
- Verify bucket prefix matches the replicator's path
- Audit storage lifecycle rules so retention cannot delete all LTX files
When it happens
Trigger: Calling restore/VFS open against a replica whose CalcRestorePlan yields zero files — e.g. a freshly configured replica that has never had a successful sync, or after all LTX files were pruned/deleted from storage.
Common situations: Pointing a VFS client at a brand-new bucket/prefix before the first litestream sync ran; wrong replica path so the listing finds nothing; retention/lifecycle rules deleted all objects; using `litestream reset` on a replica with no prior snapshots.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- detect page size: %w
- invalid replica, checksum mismatch
- open remote L0 file: %w
- encode ltx frame (pgno=%d): %w
- decode page: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/5758297c313ea735.
Report an issue: GitHub.