benbjohnson/litestream · error
fetch db position: %w
Error message
fetch db position: %w
What it means
Store.CompactDB failed reading the database's current write position via db.Pos() while shortcutting the snapshot-level compaction path. db.Pos() reads the in-memory replication position of the open database, so failures here indicate internal state inconsistency (the position is normally cached). The underlying cause is wrapped with %w.
Source
Thrown at store.go:790
return nil, &DBNotReadyError{Reason: "page size not initialized"}
}
dstLevel := lvl.Level
// Ensure we are not re-compacting before the most recent compaction time.
prevCompactionAt := lvl.PrevCompactionAt(time.Now())
dstInfo, err := db.MaxLTXFileInfo(ctx, dstLevel)
if err != nil {
return nil, fmt.Errorf("fetch dst level info: %w", err)
} else if dstInfo.CreatedAt.After(prevCompactionAt) {
return nil, ErrCompactionTooEarly
}
// Shortcut if this is a snapshot since we are not pulling from a previous level.
if dstLevel == SnapshotLevel {
pos, err := db.Pos()
if err != nil {
return nil, fmt.Errorf("fetch db position: %w", err)
}
if dstInfo.MaxTXID != 0 && dstInfo.MaxTXID >= pos.TXID {
return nil, ErrNoCompaction
}
info, err := db.Snapshot(ctx)
if err != nil {
return info, err
}
db.Logger.InfoContext(ctx, "snapshot complete", "txid", info.MaxTXID.String(), "size", info.Size)
return info, nil
}
// Fetch latest LTX files for both the source & destination so we can see if we need to make progress.
srcLevel := s.levels.PrevLevel(dstLevel)
srcInfo, err := db.MaxLTXFileInfo(ctx, srcLevel)
if err != nil {
return nil, fmt.Errorf("fetch src level info: %w", err)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Ensure the DB is open and running when compaction monitors execute; do not close the DB while compaction is in flight.
- Retry the compaction cycle; the monitor (monitorCompactionLevel) will attempt the next interval anyway.
- If persistent, restart Litestream to rebuild DB state.
- Report a bug with the wrapped error if Pos() consistently fails on a healthy, open database.
Example fix
// before
_, err := store.CompactDB(ctx, db, litestream.SnapshotLevel)
// after
_, err := store.CompactDB(ctx, db, litestream.SnapshotLevel)
if err != nil && db.SyncStatus() != litestream.SyncStatusRunning {
// skip compaction: DB not in a running state
} Defensive patterns
Strategy: retry
Validate before calling
if db.SyncStatus() != litestream.SyncStatusRunning {
return fmt.Errorf("db not running; skip compaction")
} Type guard
func dbHealthy(db *litestream.DB) bool {
return db != nil && db.SyncStatus() == litestream.SyncStatusRunning
} Try / catch
if _, err := store.CompactDB(ctx, db, litestream.SnapshotLevel); err != nil {
// compaction monitor retries next cycle; treat as recoverable
log.Printf("snapshot compaction deferred: %v", err)
} Prevention
- Avoid closing DBs while compaction monitors are active
- Restart Litestream if Pos() persistently fails
- Report persistent failures on open DBs as bugs
- Gate compaction on DB sync status
When it happens
Trigger: CompactDB(ctx, db, SnapshotLevel) where db.Pos() returns an error instead of the cached TXID position.
Common situations: Calling compaction on a DB that is in an unexpected internal state (closed concurrently, not fully initialized), or an internal bug/race between store monitoring and DB shutdown.
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 after sync: %w
- fetch dst level info: %w
- fetch src level info: %w
- compaction interval must be greater than 0
- read position before sync: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/778c08cdc206f9e2.
Report an issue: GitHub.