benbjohnson/litestream · error
page size mismatch: got %d, expected %d
Error message
page size mismatch: got %d, expected %d
What it means
FetchPage returned a page whose byte length differs from the VFS file's configured page size (f.pageSizeBytes / len(buf)). Litestream assumes every LTX page image matches the database page size; a mismatch means the replica data and the local page size disagree, so copying it would corrupt the page buffer.
Source
Thrown at vfs.go:1717
if data, ok := f.cache.Get(pgno); ok {
copy(buf, data)
return nil
}
// Get page index element
elem, ok := f.index[pgno]
if !ok {
return fmt.Errorf("page not found: %d", pgno)
}
// Fetch from remote
_, data, err := FetchPage(f.ctx, f.client, elem.Level, elem.MinTXID, elem.MaxTXID, elem.Offset, elem.Size)
if err != nil {
return err
}
if uint32(len(data)) != pageSize {
return fmt.Errorf("page size mismatch: got %d, expected %d", len(data), pageSize)
}
copy(buf, data)
f.cache.Add(pgno, data)
return nil
}
func (f *VFSFile) Truncate(size int64) error {
f.logger.Debug("truncating file", "size", size)
pageSize, err := f.pageSizeBytes()
if err != nil {
return err
}
newCommit := uint32(size / int64(pageSize))
f.mu.Lock()View on GitHub (pinned to 4ed7a308f6)
Solutions
- Verify the remote database snapshot's page size matches the local VFS database page size; do not share replicas across differently-configured databases.
- Inspect the LTX file at the indexed offset (litestream ltx -level 0) for truncation/corruption.
- Re-replicate: run litestream reset for the database so a fresh snapshot with the correct page size is created.
- Check for interrupted uploads/partial writes at the storage backend and re-upload affected LTX files.
- Ensure the client app doesn't change PRAGMA page_size on an existing replicated database.
Defensive patterns
Strategy: validation
Validate before calling
// Verify snapshot page size matches local DB before pointing VFS at a replica: // read bytes 16-17 of the DB header (page size) and compare with remote snapshot config. localPS := binary.BigEndian.Uint16(header[16:18]) // must equal replica page size
Type guard
func pageSizeOK(data []byte, want uint32) bool { return uint32(len(data)) == want } Try / catch
if err := readPageForWrite(pgno, buf); err != nil {
if strings.Contains(err.Error(), "page size mismatch") {
// stop writes; re-replicate with matching page size
}
} Prevention
- Never change PRAGMA page_size on a database that is already replicated.
- Do not reuse a replica bucket across databases with different page sizes.
- Validate LTX integrity after uploads (checksums) to catch truncation.
- Run litestream ltx to inspect remote page records after any restore.
When it happens
Trigger: Calling WriteAt (read-modify-write path) on a page present in f.index but whose stored LTX record was written with a different page size — e.g. the remote snapshot was created from a database with a different page_size, or a truncated/corrupt LTX record yields a short read.
Common situations: Pointing a VFS at a replica from a different database with a different PRAGMA page_size; restoring across litestream versions where page-size handling changed; corrupted or truncated LTX files on storage (partial upload); manually copied replica data between databases.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/13289687cb85d2fb.
Report an issue: GitHub.