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

  1. Initialize the database first (let the application create its schema) before starting Litestream.
  2. 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'.
  3. Restore the database from a backup or replica (`litestream restore`) if corrupted.
  4. 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

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


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/327651357c726bbe. Report an issue: GitHub.