{"record":{"id":"c943794fe2648f15","repo":"benbjohnson/litestream","slug":"remote-position-w","errorCode":null,"errorMessage":"remote position: %w","messagePattern":"remote position: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"db.go","lineNumber":704,"sourceCode":"\tInSync     bool\n}\n\n// SyncStatus returns the current replication status of the database, comparing\n// the local transaction position against the remote replica position. The remote\n// position is queried from the replica storage, so this method may perform I/O.\nfunc (db *DB) SyncStatus(ctx context.Context) (SyncStatus, error) {\n\tif db.Replica == nil {\n\t\treturn SyncStatus{}, fmt.Errorf(\"no replica configured\")\n\t}\n\n\tlocalPos, err := db.Pos()\n\tif err != nil {\n\t\treturn SyncStatus{}, fmt.Errorf(\"local position: %w\", err)\n\t}\n\n\tremotePos, err := db.Replica.calcPos(ctx)\n\tif err != nil {\n\t\treturn SyncStatus{}, fmt.Errorf(\"remote position: %w\", err)\n\t}\n\n\treturn SyncStatus{\n\t\tLocalTXID:  localPos.TXID,\n\t\tRemoteTXID: remotePos.TXID,\n\t\tInSync:     localPos.TXID > 0 && localPos.TXID == remotePos.TXID,\n\t}, nil\n}\n\n// SyncAndWait performs a full sync: WAL to LTX files, then LTX files to remote\n// replica. Blocks until both stages complete.\nfunc (db *DB) SyncAndWait(ctx context.Context) error {\n\tif db.Replica == nil {\n\t\treturn fmt.Errorf(\"no replica configured\")\n\t}\n\n\tif err := db.Sync(ctx); err != nil {\n\t\treturn fmt.Errorf(\"db sync: %w\", err)","sourceCodeStart":686,"sourceCodeEnd":722,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/db.go#L686-L722","documentation":"DB.SyncStatus() wraps any error from db.Replica.calcPos(ctx) with \"remote position\". calcPos determines the replica's remote TXID by querying the replica's storage backend (listing LTX files / latest snapshot). This error means the remote position could not be determined — usually a storage-backend or network failure, not a local database problem.","triggerScenarios":"Calling db.SyncStatus(ctx) when the replica client fails to list/read remote LTX info: network outage, wrong bucket/container/credentials, or an empty/invalid remote layout that calcPos cannot interpret.","commonSituations":"S3/GCS/Azure credentials expired or wrong region; replica path misconfigured after a provider migration; remote replica was reset and holds no recognizable LTX layout; transient network errors during a status check.","solutions":["Inspect the wrapped error to identify which storage backend call failed.","Verify replica client config (bucket, path/endpoint, region, credentials) with a direct listing of the replica location.","Check network connectivity / VPC endpoints to the storage provider and retry.","If remote layout is suspect, inspect it with `litestream ltx -level all` and restore/re-replicate as needed."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight: verify replica is reachable before status checks\n// e.g. list the replica root with the same client config in a health check","typeGuard":null,"tryCatchPattern":"var status SyncStatus\nvar err error\nfor i := 0; i < 3; i++ {\n    if status, err = db.SyncStatus(ctx); err == nil {\n        break\n    }\n    if !errors.Is(err, context.DeadlineExceeded) && !isTransient(err) {\n        break\n    }\n    time.Sleep(backoff)\n}","preventionTips":["Validate replica credentials and bucket/region in a startup preflight.","Set sane HTTP timeouts for the storage client.","Alert on replica listing failures separately from local DB failures.","Keep provider endpoint config (MinIO/R2) in sync with actual endpoints."],"tags":["network","storage","replica","error-wrapping"],"backgroundTag":"api-request-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}