{"record":{"id":"f647d59a767a3170","repo":"benbjohnson/litestream","slug":"cannot-seal-wal-before-passive-checkpoint-w","errorCode":null,"errorMessage":"cannot seal wal before passive checkpoint: %w","messagePattern":"cannot seal wal before passive checkpoint: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2509,"sourceCode":"\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\n\tframeSize := int64(db.pageSize + WALFrameHeaderSize)\n\tpreCheckpointFrameN := 0\n\tif exec.state.lastSyncedWALOffset > WALHeaderSize {\n\t\tpreCheckpointFrameN = int((exec.state.lastSyncedWALOffset - WALHeaderSize) / frameSize)\n\t}\n\n\t// Execute checkpoint and immediately issue a write to the WAL to ensure\n\t// a new page is written.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointExec,\n\t\tfunc(s *diagState) {\n\t\t\ts.checkpointMode = mode\n\t\t\ts.lastSyncedWALOffset = exec.state.lastSyncedWALOffset\n\t\t})\n\twalFrameN, err := db.execCheckpoint(ctx, mode)","sourceCodeStart":2491,"sourceCodeEnd":2527,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2491-L2527","documentation":"After acquiring the barrier lock in a passive checkpoint, Litestream performs one more sync to seal (fully replicate) the WAL before running the actual PRAGMA wal_checkpoint. This error wraps failure of that sealing sync, and the checkpoint is aborted to guarantee the replica has all WAL data first.","triggerScenarios":"In checkpointWithExecutor (passive mode) when db.verifyAndSyncWithExecutor(ctx, true, exec, 0) fails after the _litestream_lock insert — same causes as pre-checkpoint copy: storage failures, WAL read/encode errors, or client I/O errors.","commonSituations":"Object storage outages or expired credentials mid-checkpoint, disk full during LTX write, corrupt WAL page producing an encode error, or transient network failures.","solutions":["Inspect the wrapped inner error and fix the underlying sync failure (storage creds, network, disk)","Retry the checkpoint after storage is reachable","Run `litestream reset` only if local LTX state is confirmed corrupt","Monitor replica storage health; consider `auto-recover: true` cautiously per docs"],"exampleFix":"// before\nlitestream ltx ...   # cannot seal wal before passive checkpoint: context deadline exceeded\n// after\n# raise storage timeout / fix network, then retry\nlitestream ltx -db /var/lib/db/app.db","handlingStrategy":"retry","validationCode":"// verify storage is reachable before running passive checkpoints\nif err := storageHealthCheck(ctx); err != nil { log.Printf(\"skip checkpoint: %v\", err) }","typeGuard":null,"tryCatchPattern":"// go\nif err := checkpoint(ctx, CheckpointModePassive); err != nil {\n    if strings.Contains(err.Error(), \"cannot seal wal before passive checkpoint\") {\n        // inspect wrapped sync error (network, creds, disk) and retry after remediation\n    }\n}","preventionTips":["Monitor replica storage availability and token expiry","Keep sufficient disk headroom for LTX writes","Schedule maintenance checkpoints outside network-sensitive windows","Investigate recurring WAL sync failures — they surface here first"],"tags":["checkpoint","passive","wal-seal","sync"],"backgroundTag":"database-write-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}