benbjohnson/litestream · error
cannot determine current position: %w
Error message
cannot determine current position: %w
What it means
This error wraps a failure from r.db.Pos(), which reads the database's current replication position (TXID/page) from the local SQLite database header and WAL. Litestream needs the current position in syncOnce to compute which LTX frames still need uploading; if reading that position fails, the sync cannot proceed and the underlying cause is wrapped so the real error is preserved.
Source
Thrown at replica.go:195
}()
if err := ctx.Err(); err != nil {
return result, context.Cause(ctx)
}
// Calculate current replica position, if unknown.
if r.Pos().IsZero() {
pos, err := r.calcPos(ctx)
if err != nil {
return result, fmt.Errorf("calc pos: %w", err)
}
r.SetPos(pos)
}
// Find current position of database.
dpos, err := r.db.Pos()
if err != nil {
return result, fmt.Errorf("cannot determine current position: %w", err)
} else if dpos.IsZero() {
return result, errReplicaWaitForData
}
r.Logger().Debug("replica sync",
slog.Group("txid",
slog.String("replica", r.Pos().TXID.String()),
slog.String("db", dpos.TXID.String()),
))
// Replicate all L0 LTX files since last replica position.
for txID, syncedFileN := r.Pos().TXID+1, 0; txID <= dpos.TXID; txID = r.Pos().TXID + 1 {
if maxSyncLTXFiles > 0 && syncedFileN >= maxSyncLTXFiles {
result.limited = true
// Uploads succeeded, so record sync health; otherwise a
// sustained backlog reads as unhealthy while progressing.
r.db.RecordSuccessfulSync()
r.Logger().Debug("replica sync limited",View on GitHub (pinned to 4ed7a308f6)
Solutions
- Check the wrapped cause (%w) to see the underlying db.Pos() error and fix that (missing file, permissions, corruption).
- Verify the database path in config still exists and litestream has read/write access to the DB, WAL, and SHM files.
- Restart litestream so the DB handle is re-opened against the current database file.
- If local LTX/DB state is corrupted, run `litestream reset` for the database before resuming replication.
Defensive patterns
Strategy: try-catch
Validate before calling
// before syncing, confirm the DB is open and files are readable
if _, err := os.Stat(dbPath + "-wal"); err != nil {
return fmt.Errorf("db wal unreadable: %w", err)
}
pos, err := db.Pos()
if err != nil || pos.IsZero() {
return fmt.Errorf("db not ready for sync: %w", err)
} Try / catch
if err := replica.Sync(ctx); err != nil {
var wrapped interface{ Unwrap() error }
if errors.As(err, &cause) && strings.Contains(err.Error(), "cannot determine current position") {
log.Printf("db position unreadable, resetting local state: %v", cause)
}
} Prevention
- Keep the DB, WAL, and SHM files on a reliable local filesystem with correct permissions
- Avoid deleting or moving the database while litestream is replicating
- Monitor the wrapped cause of sync errors, not just the top-level message
When it happens
Trigger: Replica.syncOnce (or sync) runs while the underlying DB handle cannot read its position — e.g. the database file was deleted/moved, the DB is not open, WAL/SHM files are unreadable, or the db metadata read returns an I/O or SQLite error. Callers: TestReplica_SyncOnceLimitsLTXFiles and Replica.sync.
Common situations: Database file removed or corrupted while litestream is running; DB closed concurrently; running on a filesystem where the WAL/SHM can't be read (permissions, NFS issues); pointing a replica at a database path that no longer exists.
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
- replica required before opening database
- replica client required before opening database
- cannot copy wal before checkpoint: %w
- cannot copy wal after passive checkpoint: %w
- cannot copy wal after checkpoint: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/7d378206c9457170.
Report an issue: GitHub.