benbjohnson/litestream · critical
sync database %s: %w
Error message
sync database %s: %w
What it means
In one-shot (`-once`) mode, runOnce syncs each configured database (applying pending WAL changes and uploading LTX files) and returns the first error via named return. A failure from db.Sync — corrupted WAL, locked database, I/O error — is wrapped as "sync database <path>" so the failing database is identified.
Source
Thrown at cmd/litestream/replicate.go:403
// Run one-shot replication in a goroutine so the caller can wait on execCh.
go c.runOnce(ctx)
}
return nil
}
// runOnce performs one-shot replication for all databases.
// It syncs all databases, optionally takes snapshots, and enforces retention.
func (c *ReplicateCommand) runOnce(ctx context.Context) {
var err error
defer func() { c.execCh <- err }()
for _, db := range c.Store.DBs() {
slog.Info("syncing database", "path", db.Path())
// Sync the database to process any pending WAL changes.
if err = db.Sync(ctx); err != nil {
err = fmt.Errorf("sync database %s: %w", db.Path(), err)
return
}
// Sync the replica to upload any pending LTX files.
if err = db.Replica.Sync(ctx); err != nil {
err = fmt.Errorf("sync replica for %s: %w", db.Path(), err)
return
}
// Force a snapshot if requested.
if c.forceSnapshot {
slog.Info("taking snapshot", "path", db.Path())
if _, err = db.Snapshot(ctx); err != nil {
err = fmt.Errorf("snapshot %s: %w", db.Path(), err)
return
}
}
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Inspect the wrapped inner error for the SQLite-level cause (lock, corruption, I/O)
- Retry the one-shot sync once the writer releases locks / quiesce the application
- If local LTX/WAL state is corrupted, run `litestream reset` for that database and re-sync
- Ensure litestream runs with read/write access to the DB, WAL, and SHM files
Example fix
null
Defensive patterns
Strategy: try-catch
Validate before calling
# pre-check DB accessibility before one-shot sync
[ -f "$DB" ] && [ -w "${DB}-wal" ] || echo "warn: wal missing/unwritable"
lsof "$DB" && echo "warn: database in use by another process" Try / catch
if err := cmd.Run(ctx); err != nil {
var dbErr error
if strings.Contains(err.Error(), "sync database") {
dbErr = err // path is embedded in message; unwrap for SQLite cause
for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(e) {
log.Printf("sqlite cause: %v", e)
}
}
return err
} Prevention
- Schedule one-shot syncs when writers are quiescent or accept brief locks
- Ensure litestream has rw access to DB, -wal and -shm files
- Avoid running multiple litestream instances against the same database
- Use `litestream reset` only when local LTX state is confirmed corrupted
- Monitor disk space — full disks break WAL checkpointing and syncs
When it happens
Trigger: `db.Sync(ctx)` returns error during a `-once` run: the SQLite file is locked by another process, WAL is corrupted, disk is full, or the DB was modified concurrently in an unsupported way.
Common situations: Another process holds an exclusive lock during the one-shot backup; WAL/shm files out of sync after a crash; running litestream as a different user than the app writing the DB.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- set synchronous: %w
- checkpoint: %w
- checkpoint failed: %w
- enable wal failed, mode=%q
- acquire read lock: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/d21d58c99cbde53f.
Report an issue: GitHub.