benbjohnson/litestream · error
read position after sync: %w
Error message
read position after sync: %w
What it means
Store.SyncDB failed after a successful sync because db.MaxLTX() could not read the post-sync replication position. Since the sync succeeded, this usually indicates a problem reading local LTX position metadata or an unexpected internal state, not a replication failure. The wrapped error is returned with %w.
Source
Thrown at store.go:460
_, beforeTXID, err := db.MaxLTX()
if err != nil {
return SyncDBResult{}, fmt.Errorf("read position before sync: %w", err)
}
if wait {
if err := db.SyncAndWait(ctx); err != nil {
return SyncDBResult{}, fmt.Errorf("sync database: %w", err)
}
} else {
if err := db.Sync(ctx); err != nil {
return SyncDBResult{}, fmt.Errorf("sync database: %w", err)
}
}
_, afterTXID, err := db.MaxLTX()
if err != nil {
return SyncDBResult{}, fmt.Errorf("read position after sync: %w", err)
}
var replicatedTXID uint64
if db.Replica != nil {
replicatedTXID = uint64(db.Replica.Pos().TXID)
}
return SyncDBResult{
TXID: uint64(afterTXID),
ReplicatedTXID: replicatedTXID,
Changed: afterTXID > beforeTXID,
}, nil
}
// FindDB returns the database with the given path.
func (s *Store) FindDB(path string) *DB {
s.mu.Lock()
defer s.mu.Unlock()View on GitHub (pinned to 4ed7a308f6)
Solutions
- Re-run SyncDB; if the before-sync read (store.go:445) also fails, treat it as a local-state problem rather than a sync problem.
- Inspect local LTX/replica position files for corruption; run litestream reset to clear corrupted local state for that database.
- Check filesystem health and permissions on the Litestream data directory.
- Avoid closing/unregistering the DB concurrently with SyncDB calls; serialize lifecycle operations.
Example fix
// before
res, err := store.SyncDB(ctx, path, true)
// after
res, err := store.SyncDB(ctx, path, true)
if err != nil {
// sync may have succeeded; verify position before retrying aggressively
log.Printf("SyncDB %s: %v", path, err)
return err
} Defensive patterns
Strategy: try-catch
Try / catch
res, err := store.SyncDB(ctx, path, true)
if err != nil {
// sync may have succeeded; check error position to decide retry
log.Printf("SyncDB %s failed: %v", path, err)
return err
} Prevention
- Don't close/unregister the DB concurrently with SyncDB
- Check local LTX state integrity if this recurs
- Log the wrapped error to distinguish position-read vs sync failures
- Report persistent failures on healthy DBs as upstream bugs
When it happens
Trigger: SyncDB(ctx, path, wait) completes db.Sync/SyncAndWait successfully, but the subsequent db.MaxLTX() call errors while enumerating local LTX files to compute the after TXID.
Common situations: Local LTX metadata corruption, filesystem errors after the sync (disk removed, permissions changed mid-call), or a bug/race where the DB was closed concurrently between sync and position read.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- read position before sync: %w
- sync database: %w
- fetch db position: %w
- fetch dst level info: %w
- fetch src level info: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/4150dbf2b6f9fe07.
Report an issue: GitHub.