benbjohnson/litestream · error
invalid db page size: %d
Error message
invalid db page size: %d
What it means
Litestream read a page size from `PRAGMA page_size` that is zero or negative, which is impossible for a valid SQLite database. Litestream rejects it because it cannot map database pages into WAL frames without a valid page size. This almost always means the file is not an initialized SQLite database or the header is corrupt.
Source
Thrown at db.go:1105
}
// 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 {
return fmt.Errorf("check database behind replica: %w", err)
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Initialize the database first (let the application create its schema) before starting Litestream.
- If the file should be a valid DB, check its size and header: a valid SQLite file is a multiple of the page size and starts with 'SQLite format 3\000'.
- Restore the database from a backup or replica (`litestream restore`) if corrupted.
- Verify you configured the correct path in the config file.
Example fix
// before # litestream.yml points at /data/app.db which is 0 bytes // after # start the app first so it creates the schema, then start litestream systemctl start app && systemctl start litestream
Defensive patterns
Strategy: validation
Validate before calling
// verify before opening: initialized DB with nonzero size and page size
const st = fs.statSync(dbPath);
if (st.size === 0) throw new Error('db file is empty; initialize it before running litestream');
const out = execSync(`sqlite3 ${dbPath} 'PRAGMA page_size;'`).toString().trim();
if (!out || parseInt(out, 10) <= 0) throw new Error('invalid page size: ' + out); Type guard
function isInitializedSqliteDb(p) {
try { const b = fs.readFileSync(p).subarray(0, 16); return b.length === 16 && b.toString('latin1') === 'SQLite format 3\u0000'; } catch { return false; }
} Try / catch
try {
await db.Open(ctx);
} catch (err) {
if (String(err.message).includes('invalid db page size')) {
// file is empty or corrupt: run `litestream restore` or let the app initialize the schema first
}
} Prevention
- Create the application schema before starting Litestream on a fresh path.
- Check config paths carefully (empty placeholder files at wrong paths are a common cause).
- Run PRAGMA integrity_check as a deployment health check.
- Restore from replica instead of using a zeroed/corrupt file.
When it happens
Trigger: db.init scans `PRAGMA page_size` into db.pageSize and the value is <= 0 — seen when the target file is empty (zero bytes), not yet initialized by SQLite, or its 100-byte header is zeroed/corrupted.
Common situations: Pointing Litestream at a path where the application hasn't created the database yet (empty file created by a touch or by the app but not initialized); copying an empty placeholder file; truncated/corrupted header after a crash on flaky storage.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- read page size: %w
- set PERSIST_WAL: %w
- create _litestream_seq table: %w
- create _litestream_lock table: %w
- acquire read lock: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/327651357c726bbe.
Report an issue: GitHub.