benbjohnson/litestream · error

db sync: %w

Error message

db sync: %w

What it means

DB.SyncAndWait() wraps an error from the first stage, db.Sync(ctx), with "db sync". db.Sync rolls the local WAL into LTX files locally; a failure here means the local checkpoint/compaction step failed — replication never started. The root cause is chained via %w.

Source

Thrown at db.go:722

		return SyncStatus{}, fmt.Errorf("remote position: %w", err)
	}

	return SyncStatus{
		LocalTXID:  localPos.TXID,
		RemoteTXID: remotePos.TXID,
		InSync:     localPos.TXID > 0 && localPos.TXID == remotePos.TXID,
	}, nil
}

// SyncAndWait performs a full sync: WAL to LTX files, then LTX files to remote
// replica. Blocks until both stages complete.
func (db *DB) SyncAndWait(ctx context.Context) error {
	if db.Replica == nil {
		return fmt.Errorf("no replica configured")
	}

	if err := db.Sync(ctx); err != nil {
		return fmt.Errorf("db sync: %w", err)
	}
	if err := db.Replica.Sync(ctx); err != nil {
		return fmt.Errorf("replica sync: %w", err)
	}
	return nil
}

// EnsureExists restores the database from the configured replica if the local
// database file does not exist. If no backup is available, it returns nil and
// a fresh database will be created on Open(). Must be called before Open().
func (db *DB) EnsureExists(ctx context.Context) error {
	if db.Replica == nil {
		return fmt.Errorf("no replica configured")
	}
	if db.Replica.Client == nil {
		return fmt.Errorf("no replica client configured")
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Unwrap the error to see the underlying SQLite/LTX failure.
  2. Verify the DB is open (Open() called) and the data directory has writable space.
  3. Check for competing SQLite writers/locks on the database.
  4. If local LTX state is corrupted, use `litestream reset` / auto-recover to clear it, then re-sync.
Defensive patterns

Strategy: retry

Validate before calling

if _, err := os.Stat(db.Path()); err != nil {
    return fmt.Errorf("db missing, sync will fail: %w", err)
}

Try / catch

if err := db.SyncAndWait(ctx); err != nil {
    var wrapped interface{ Unwrap() error }
    _ = wrapped
    log.Error("local sync stage failed", "err", err)
    // inspect errors.Is(err, sqliteErr) etc.
}

Prevention

When it happens

Trigger: Calling db.SyncAndWait(ctx) when db.Sync fails: SQLite checkpoint errors, WAL read errors, failure writing local LTX files, or the DB not being open/initialized.

Common situations: Corrupted WAL after a crash; disk full while writing LTX files; another process holding SQLite locks preventing checkpointing; calling SyncAndWait before Open().

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/ae45b1ab8ea91052. Report an issue: GitHub.