{"record":{"id":"bed8f96070dfd82c","repo":"benbjohnson/litestream","slug":"begin-passive-checkpoint-barrier-w","errorCode":null,"errorMessage":"begin passive checkpoint barrier: %w","messagePattern":"begin passive checkpoint barrier: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2495,"sourceCode":"\t}\n\n\t// Copy end of WAL before checkpoint to copy as much as possible.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointCopyBefore,\n\t\tfunc(s *diagState) {\n\t\t\ts.checkpointMode = mode\n\t\t\ts.lastSyncedWALOffset = exec.state.lastSyncedWALOffset\n\t\t})\n\tresult, err := db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"cannot copy wal before checkpoint: %w\", err)\n\t}\n\texec.applySyncResult(result)\n\n\tvar barrierTx *sql.Tx\n\tif mode == CheckpointModePassive {\n\t\tbarrierTx, err = db.db.BeginTx(ctx, nil)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"begin passive checkpoint barrier: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif barrierTx != nil {\n\t\t\t\t_ = rollback(barrierTx)\n\t\t\t}\n\t\t}()\n\n\t\tif _, err := barrierTx.ExecContext(ctx, `INSERT INTO _litestream_lock (id) VALUES (1);`); err != nil {\n\t\t\treturn false, fmt.Errorf(\"_litestream_lock: %w\", err)\n\t\t}\n\n\t\tresult, err = db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"cannot seal wal before passive checkpoint: %w\", err)\n\t\t}\n\t\texec.applySyncResult(result)\n\t}\n","sourceCodeStart":2477,"sourceCodeEnd":2513,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2477-L2513","documentation":"For passive checkpoints, Litestream opens a barrier transaction (BeginTx) on the SQLite database to hold a read lock during the checkpoint. This error wraps a failure to begin that transaction, so the passive checkpoint cannot proceed safely.","triggerScenarios":"In checkpointWithExecutor, mode == CheckpointModePassive, when db.db.BeginTx(ctx, nil) returns an error — database locked beyond busy timeout, database closed, or context canceled.","commonSituations":"Another process holds a long write transaction (locking the DB), the database is in a locking dispute with other tooling, or Litestream is shutting down (context canceled) when the checkpoint fires.","solutions":["Identify blocking writers (`PRAGMA busy_timeout;`, `sqlite3 app.db '.timeout'` or lsof on the db) and let them finish","Increase the busy timeout / reduce long-running write transactions in the application","Avoid forcing checkpoints during application write bursts; rely on the normal checkpoint cadence","Retry after the lock clears — the error is typically transient"],"exampleFix":"// before\napp: single long transaction holding write lock for minutes\nlitestream: begin passive checkpoint barrier: database is locked\n// after\n-- break long transactions into smaller commits\n-- and/or set busy_timeout\nPRAGMA busy_timeout = 5000;","handlingStrategy":"try-catch","validationCode":"// avoid forcing passive checkpoints while heavy writers run\nif longWriteTxActive(app) { log.Printf(\"defer checkpoint\") }","typeGuard":null,"tryCatchPattern":"// go\nif err := checkpoint(ctx, CheckpointModePassive); err != nil {\n    if strings.Contains(err.Error(), \"begin passive checkpoint barrier\") {\n        // database locked/closed: retry with backoff; check for blocking writers\n    }\n}","preventionTips":["Keep application write transactions short","Set a reasonable busy_timeout in SQLite","Don't force checkpoints during peak write load or shutdown","Only one checkpoint coordinator per database"],"tags":["sqlite","checkpoint","database-locked","transaction"],"backgroundTag":"database-query-failed","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"}