benbjohnson/litestream · error
calc pos: %w
Error message
calc pos: %w
What it means
During the first sync of a replica, syncOnce must determine the replica's current TXID position by listing remote LTX files (calcPos). If that discovery fails — unreadable/missing LTX header, listing error, or no usable files — the error is wrapped as 'calc pos'. Litestream cannot know where the replica stands and aborts the sync.
Source
Thrown at replica.go:187
// Clear last position if if an error occurs during sync.
defer func() {
if err != nil {
r.mu.Lock()
r.pos = ltx.Pos{}
r.mu.Unlock()
}
}()
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()),
))
View on GitHub (pinned to 4ed7a308f6)
Solutions
- Inspect the wrapped error: if listing failed, fix credentials/region (see OSS GET/LIST errors); if a header is corrupt, the remote copy is damaged.
- Run 'litestream ltx -level all' / 'litestream replicas' against the replica to see what files exist remotely.
- For a genuinely empty/invalid remote state, run 'litestream reset <db>' to clear local LTX state and re-sync from scratch (or enable the auto-recover replica option to do this automatically).
- If the latest LTX file is truncated, restore from an earlier complete generation and re-establish replication.
Example fix
// before
replicas:
- type: oss
bucket: my-bucket
path: db/ltx
// after (auto-recover clears bad local LTX state and re-syncs)
replicas:
- type: oss
bucket: my-bucket
path: db/ltx
auto-recover: true Defensive patterns
Strategy: fallback
Try / catch
if err := replica.Sync(ctx); err != nil && strings.Contains(err.Error(), "calc pos") {
// clear bad local LTX state and resync
if rerr := resetAndResync(ctx); rerr != nil { return rerr }
} Prevention
- Enable the auto-recover replica option so bad local LTX state resets automatically on position errors.
- Monitor 'litestream replicas' output for zero/unknown TXID after startup.
- Don't manually delete or edit LTX objects in the replica bucket.
- Keep credentials valid for both LIST and GET so initial position discovery can succeed.
When it happens
Trigger: First sync after registering a replica when calcPos cannot read the latest LTX header: remote listing fails (403/404), the newest LTX file is corrupt/truncated, or the replica path contains no valid LTX files.
Common situations: Fresh replica pointing at an empty bucket path; remote files truncated by a failed earlier upload; credentials allowing listing but not reading; network blip during the initial position discovery. Also surfaces in TestReplica_SyncOnceLimitsLTXFiles when fixtures are malformed.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/9af96379b195a76d.
Report an issue: GitHub.