benbjohnson/litestream · error
read page size: %w
Error message
read page size: %w
What it means
Litestream failed to read the database page size via `PRAGMA page_size` during init. Page size is required to interpret WAL frames and build LTX files. The error wraps the driver-level Scan error — typically a locked/closed connection, context cancellation, or an unreadable database header.
Source
Thrown at db.go:1103
if _, err := db.db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS _litestream_seq (id INTEGER PRIMARY KEY, seq INTEGER);`); err != nil {
return fmt.Errorf("create _litestream_seq table: %w", err)
}
// Create a lock table to force write locks during sync.
// The sync write transaction always rolls back so no data should be in this table.
if _, err := db.db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS _litestream_lock (id INTEGER);`); err != nil {
return fmt.Errorf("create _litestream_lock table: %w", err)
}
// Start a long-running read transaction to prevent other transactions
// from checkpointing.
if err := db.acquireReadLock(ctx); err != nil {
return fmt.Errorf("acquire read lock: %w", err)
}
// Read page size.
if err := db.db.QueryRowContext(ctx, `PRAGMA page_size;`).Scan(&db.pageSize); err != nil {
return fmt.Errorf("read page size: %w", err)
} else if db.pageSize <= 0 {
return fmt.Errorf("invalid db page size: %d", db.pageSize)
}
// Ensure meta directory structure exists.
if err := internal.MkdirAll(db.metaPath, db.dirInfo); err != nil {
return err
}
// Ensure WAL has at least one frame in it.
if err := db.ensureWALExists(ctx); err != nil {
return fmt.Errorf("ensure wal exists: %w", err)
}
// Check if database is behind replica (issue #781).
// This must happen before replica.Start() to detect restore scenarios.
if db.Replica != nil {
if err := db.checkDatabaseBehindReplica(ctx); err != nil {View on GitHub (pinned to 4ed7a308f6)
Solutions
- Confirm the database file still exists and is a valid SQLite file (`sqlite3 file 'PRAGMA page_size;'` directly).
- Restore the database from backup if the header is corrupted.
- Increase/fix the context passed to Open so slow starts aren't cancelled.
- Re-run Litestream; if transient (network FS), move the DB to local storage.
Example fix
// before # file copied with `cp` mid-write -> 'file is not a database' // after sqlite3 app.db '.backup app.db.bak' && mv app.db.bak app.db # consistent copy, then restart litestream
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: readable file with valid sqlite header
const hdr = fs.readFileSync(dbPath).subarray(0, 16).toString('latin1');
if (!hdr.startsWith('SQLite format 3')) throw new Error('invalid sqlite header'); Type guard
function hasSqliteHeader(p) {
try { const fd = fs.openSync(p, 'r'); const b = Buffer.alloc(16); fs.readSync(fd, b, 0, 16, 0); fs.closeSync(fd); return b.toString('latin1').startsWith('SQLite format 3'); } catch { return false; }
} Try / catch
try {
await db.Open(ctx);
} catch (err) {
if (String(err.message).includes('read page size')) {
logger.error('cannot read page size; check file integrity', { cause: err.cause });
// fall back to `litestream restore` into a fresh file
}
} Prevention
- Never copy/replace the live DB file with a partial write; use sqlite3 .backup or VACUUM INTO.
- Restore from replica if integrity_check fails.
- Avoid storage that truncates files on crash.
- Don't cancel the Open context mid-init.
When it happens
Trigger: The `QueryRowContext(ctx, "PRAGMA page_size;").Scan(&db.pageSize)` call fails during db.init: connection lost, context cancelled, file unreadable/corrupt header so SQLite cannot respond, or database file replaced/deleted between open and this query.
Common situations: Database file deleted or truncated while Litestream is initializing; corrupted header from a partial file copy; context deadline exceeded during a slow start; running against an unsupported/foreign file format.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/897676eb2a11ffe9.
Report an issue: GitHub.