benbjohnson/litestream · error
cannot copy wal before checkpoint: %w
Error message
cannot copy wal before checkpoint: %w
What it means
Before a checkpoint, Litestream must copy (seal) all pending WAL frames into an LTX file via verifyAndSyncWithExecutor. This error wraps any failure in that pre-checkpoint sync, meaning the WAL could not be fully replicated before checkpointing, so the checkpoint is aborted to avoid data loss.
Source
Thrown at db.go:2487
db.setSyncDiagPhase(diagPhaseCheckpointReadWALHeader,
func(s *diagState) {
s.checkpointMode = mode
s.lastSyncedWALOffset = exec.state.lastSyncedWALOffset
})
hdr, err := readWALHeader(db.WALPath())
if err != nil {
return false, err
}
// Copy end of WAL before checkpoint to copy as much as possible.
db.setSyncDiagPhase(diagPhaseCheckpointCopyBefore,
func(s *diagState) {
s.checkpointMode = mode
s.lastSyncedWALOffset = exec.state.lastSyncedWALOffset
})
result, err := db.verifyAndSyncWithExecutor(ctx, true, exec, 0)
if err != nil {
return false, fmt.Errorf("cannot copy wal before checkpoint: %w", err)
}
exec.applySyncResult(result)
var barrierTx *sql.Tx
if mode == CheckpointModePassive {
barrierTx, err = db.db.BeginTx(ctx, nil)
if err != nil {
return false, fmt.Errorf("begin passive checkpoint barrier: %w", err)
}
defer func() {
if barrierTx != nil {
_ = rollback(barrierTx)
}
}()
if _, err := barrierTx.ExecContext(ctx, `INSERT INTO _litestream_lock (id) VALUES (1);`); err != nil {
return false, fmt.Errorf("_litestream_lock: %w", err)
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check the wrapped inner error: if it's storage/auth related, fix credentials/network and verify with `litestream replicate` logs
- Free disk space if local LTX writes failed
- Run `litestream reset` only if local LTX state is corrupt (accepting re-upload)
- Retry once storage is healthy; the checkpoint will be reattempted on the next sync
Example fix
// before # checkpoint fails: cannot copy wal before checkpoint: s3: ... AccessDenied // after # fix IAM policy so s3:PutObject is allowed, then litestream ltx -db /var/lib/db/app.db
Defensive patterns
Strategy: retry
Validate before calling
// probe replica storage writability before triggering a checkpoint
if err := replicaClientProbe(ctx); err != nil { log.Printf("storage unavailable: %v", err) } Try / catch
// go
if err := checkpoint(ctx, mode); err != nil {
if strings.Contains(err.Error(), "cannot copy wal before checkpoint") {
// inspect wrapped cause (S3 AccessDenied, ENOSPC...) and retry after fix
}
} Prevention
- Verify IAM/storage credentials regularly (s3:PutObject etc.)
- Monitor disk free space on the litestream host
- Alert on replication lag so syncs don't fail silently
- Test storage reachability before maintenance windows
When it happens
Trigger: In checkpointWithExecutor when the initial db.verifyAndSyncWithExecutor(ctx, true, exec, 0) returns an error — replica client I/O failure, LTX write error, or WAL read error during the copy.
Common situations: Object storage unreachable (S3 creds/expired tokens, network outage), disk full, corrupt WAL preventing page encoding, or replica write permission problems.
Related errors
- cannot copy wal after passive checkpoint: %w
- cannot copy wal after checkpoint: %w
- cannot snapshot after checkpoint: %w
- checkpoint: %w
- checkpoint failed: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/d1eafa6792a465e9.
Report an issue: GitHub.