{"record":{"id":"ea44652578c9d297","repo":"benbjohnson/litestream","slug":"cannot-copy-wal-after-passive-checkpoint-w","errorCode":null,"errorMessage":"cannot copy wal after passive checkpoint: %w","messagePattern":"cannot copy wal after passive checkpoint: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":2561,"sourceCode":"\t// If WAL hasn't been restarted, exit.\n\tdb.setSyncDiagPhase(diagPhaseCheckpointVerifyRestart,\n\t\tfunc(s *diagState) {\n\t\t\ts.checkpointMode = mode\n\t\t\ts.lastSyncedWALOffset = exec.state.lastSyncedWALOffset\n\t\t})\n\tother, err := readWALHeader(db.WALPath())\n\tif err != nil {\n\t\treturn false, err\n\t} else if bytes.Equal(hdr, other) {\n\t\texec.state.syncedSinceCheckpoint = false\n\t\treturn false, nil\n\t}\n\texec.state.truncatePassiveFailed = false\n\n\tif mode == CheckpointModePassive {\n\t\tresult, err = db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"cannot copy wal after passive checkpoint: %w\", err)\n\t\t}\n\t\texec.applySyncResult(result)\n\t\texec.state.syncedSinceCheckpoint = false\n\t\treturn true, nil\n\t}\n\n\t// A successful TRUNCATE checkpoint always reports zero frames because\n\t// the WAL is reset before the counters are read, so the comparison\n\t// below can never prove that no commits landed between the sealed\n\t// sync and the checkpoint taking the writer lock. Those commits are\n\t// backfilled and truncated unseen, so TRUNCATE must take the boundary\n\t// snapshot unconditionally.\n\tif mode != CheckpointModeTruncate && walFrameN <= preCheckpointFrameN {\n\t\tresult, err = db.verifyAndSyncWithExecutor(ctx, true, exec, 0)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"cannot copy wal after checkpoint: %w\", err)\n\t\t}\n\t\texec.applySyncResult(result)","sourceCodeStart":2543,"sourceCodeEnd":2579,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L2543-L2579","documentation":"After a PASSIVE checkpoint, Litestream must copy any WAL frames that accumulated since the checkpoint back into its replication stream via verifyAndSyncWithExecutor. If that sync fails, the checkpoint is reported as failed with this error. It means WAL frames written after the checkpoint were not captured and replication state is now inconsistent until a successful sync.","triggerScenarios":"mode == CheckpointModePassive and db.verifyAndSyncWithExecutor(ctx, true, exec, 0) returns an error immediately after the passive checkpoint: WAL read failure, checksum mismatch in the WAL, LTX write failure to the replica storage, or SQLITE_BUSY reading the db.","commonSituations":"Replica storage backend (S3, file, etc.) temporarily unavailable or returning errors during the post-checkpoint copy; corrupt or externally truncated WAL file; network interruption to cloud storage mid-sync.","solutions":["Look at the wrapped error to determine whether the failure is on the WAL read side or the replica storage write side.","Verify replica storage connectivity/credentials (e.g. S3 bucket reachable) and retry the sync.","If the WAL appears corrupt or state is inconsistent, use 'litestream reset' for the database to rebuild local LTX state.","Enable 'auto-recover' on the replica if you want Litestream to reset local state automatically on LTX errors."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := replicaClientHealthCheck(ctx); err != nil { /* verify storage backend reachable before syncing */ }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"cannot copy wal after passive checkpoint\") {\n    log.Printf(\"post-checkpoint WAL copy failed: %v\", err)\n    // backoff and retry; consider litestream reset if persistent\n}","preventionTips":["Monitor replica storage reachability and credentials expiry.","Do not truncate or modify the WAL file externally.","Enable 'auto-recover' on the replica for automatic state reset on LTX errors.","Alert on consecutive sync failures."],"tags":["wal","checkpoint","sync","replication"],"backgroundTag":"wal-sync-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"}