benbjohnson/litestream · error
no replica configured
Error message
no replica configured
What it means
SyncStatus compares the local transaction position against the remote replica position, so it requires db.Replica to be configured. When the database was opened without a replica (local monitoring only), it returns the plain error 'no replica configured'.
Source
Thrown at db.go:694
func (db *DB) LastSuccessfulSyncAt() time.Time {
db.lastSuccessfulSyncMu.RLock()
defer db.lastSuccessfulSyncMu.RUnlock()
return db.lastSuccessfulSyncAt
}
// SyncStatus represents the current replication state of the database.
type SyncStatus struct {
LocalTXID ltx.TXID
RemoteTXID ltx.TXID
InSync bool
}
// SyncStatus returns the current replication status of the database, comparing
// the local transaction position against the remote replica position. The remote
// position is queried from the replica storage, so this method may perform I/O.
func (db *DB) SyncStatus(ctx context.Context) (SyncStatus, error) {
if db.Replica == nil {
return SyncStatus{}, fmt.Errorf("no replica configured")
}
localPos, err := db.Pos()
if err != nil {
return SyncStatus{}, fmt.Errorf("local position: %w", err)
}
remotePos, err := db.Replica.calcPos(ctx)
if err != nil {
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
}View on GitHub (pinned to 4ed7a308f6)
Solutions
- Add a replica section to the config for that database path and reload litestream
- Attach a replica programmatically before calling SyncStatus
- If the database is intentionally replica-less, guard the call: skip SyncStatus when db.Replica == nil and report a non-replicating status
- Verify the correct config file was loaded (a default/minimal config may omit replicas)
Example fix
// before
status, err := db.SyncStatus(ctx)
// after: guard when replication may be absent
if db.Replica == nil {
return SyncStatusNotReplicating, nil
}
status, err := db.SyncStatus(ctx) Defensive patterns
Strategy: type-guard
Validate before calling
// Check replica presence before calling SyncStatus
if db.Replica == nil {
return SyncStatus{}, errors.New("db has no replica; skipping status check")
} Type guard
func hasReplica(db *litestream.DB) bool { return db.Replica != nil } Try / catch
if !hasReplica(db) {
return SyncStatusNone, nil
}
status, err := db.SyncStatus(ctx)
if err != nil {
return SyncStatusUnknown, fmt.Errorf("sync status: %w", err)
} Prevention
- Include a [[replica]] section for every database you monitor
- Add config validation at startup that errors on replica-less monitored DBs
- In library code, always branch on db.Replica == nil before remote status calls
When it happens
Trigger: Calling db.SyncStatus(ctx) (library API) on a DB opened without a replica attached — e.g. config file with no [[replica]] section for the database, or a Replica-less DB constructed programmatically.
Common situations: Deploying a config where a database block exists but replication was never configured (or was commented out); calling SyncStatus in monitoring code against a DB used only for restore; version changes where replicas became optional.
Understand the failure class
Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.
Related errors
- no replica client configured
- database config required
- store required
- snapshot interval must be greater than 0
- snapshot retention must be greater than 0
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/a9dbf070394eeb08.
Report an issue: GitHub.