{"record":{"id":"327651357c726bbe","repo":"benbjohnson/litestream","slug":"invalid-db-page-size-d","errorCode":null,"errorMessage":"invalid db page size: %d","messagePattern":"invalid db page size: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":1105,"sourceCode":"\t}\n\n\t// Create a lock table to force write locks during sync.\n\t// The sync write transaction always rolls back so no data should be in this table.\n\tif _, err := db.db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS _litestream_lock (id INTEGER);`); err != nil {\n\t\treturn fmt.Errorf(\"create _litestream_lock table: %w\", err)\n\t}\n\n\t// Start a long-running read transaction to prevent other transactions\n\t// from checkpointing.\n\tif err := db.acquireReadLock(ctx); err != nil {\n\t\treturn fmt.Errorf(\"acquire read lock: %w\", err)\n\t}\n\n\t// Read page size.\n\tif err := db.db.QueryRowContext(ctx, `PRAGMA page_size;`).Scan(&db.pageSize); err != nil {\n\t\treturn fmt.Errorf(\"read page size: %w\", err)\n\t} else if db.pageSize <= 0 {\n\t\treturn fmt.Errorf(\"invalid db page size: %d\", db.pageSize)\n\t}\n\n\t// Ensure meta directory structure exists.\n\tif err := internal.MkdirAll(db.metaPath, db.dirInfo); err != nil {\n\t\treturn err\n\t}\n\n\t// Ensure WAL has at least one frame in it.\n\tif err := db.ensureWALExists(ctx); err != nil {\n\t\treturn fmt.Errorf(\"ensure wal exists: %w\", err)\n\t}\n\n\t// Check if database is behind replica (issue #781).\n\t// This must happen before replica.Start() to detect restore scenarios.\n\tif db.Replica != nil {\n\t\tif err := db.checkDatabaseBehindReplica(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"check database behind replica: %w\", err)\n\t\t}","sourceCodeStart":1087,"sourceCodeEnd":1123,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L1087-L1123","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n# litestream.yml points at /data/app.db which is 0 bytes\n// after\n# start the app first so it creates the schema, then start litestream\nsystemctl start app && systemctl start litestream","handlingStrategy":"validation","validationCode":"// verify before opening: initialized DB with nonzero size and page size\nconst st = fs.statSync(dbPath);\nif (st.size === 0) throw new Error('db file is empty; initialize it before running litestream');\nconst out = execSync(`sqlite3 ${dbPath} 'PRAGMA page_size;'`).toString().trim();\nif (!out || parseInt(out, 10) <= 0) throw new Error('invalid page size: ' + out);","typeGuard":"function isInitializedSqliteDb(p) {\n  try { const b = fs.readFileSync(p).subarray(0, 16); return b.length === 16 && b.toString('latin1') === 'SQLite format 3\\u0000'; } catch { return false; }\n}","tryCatchPattern":"try {\n  await db.Open(ctx);\n} catch (err) {\n  if (String(err.message).includes('invalid db page size')) {\n    // file is empty or corrupt: run `litestream restore` or let the app initialize the schema first\n  }\n}","preventionTips":["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."],"tags":["sqlite","page-size","corruption","init"],"backgroundTag":"value-out-of-range","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}