{"record":{"id":"330deb6a8c67db7c","repo":"benbjohnson/litestream","slug":"write-ltx-file-w","errorCode":null,"errorMessage":"write ltx file: %w","messagePattern":"write ltx file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"replica.go","lineNumber":258,"sourceCode":"\tr.syncWaiters.Add(1)\n\tdefer r.syncWaiters.Add(-1)\n\tif err := r.syncSem.Acquire(ctx, 1); err != nil {\n\t\treturn fmt.Errorf(\"wait for replica sync: %w\", context.Cause(ctx))\n\t}\n\treturn nil\n}\n\nfunc (r *Replica) uploadLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID) (err error) {\n\tfilename := r.db.LTXPath(level, minTXID, maxTXID)\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\treturn NewLTXError(\"open\", filename, level, uint64(minTXID), uint64(maxTXID), err)\n\t}\n\tdefer func() { _ = f.Close() }()\n\n\tinfo, err := r.Client.WriteLTXFile(ctx, level, minTXID, maxTXID, f)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"write ltx file: %w\", err)\n\t}\n\tr.Logger().Debug(\"ltx file uploaded\",\n\t\t\"level\", info.Level,\n\t\t\"minTXID\", info.MinTXID,\n\t\t\"maxTXID\", info.MaxTXID,\n\t\t\"size\", info.Size)\n\n\t// Track current position\n\t//replicaWALIndexGaugeVec.WithLabelValues(r.db.Path(), r.Name()).Set(float64(rd.Pos().Index))\n\t//replicaWALOffsetGaugeVec.WithLabelValues(r.db.Path(), r.Name()).Set(float64(rd.Pos().Offset))\n\n\treturn nil\n}\n\n// calcPos returns the last position saved to the replica for level 0.\nfunc (r *Replica) calcPos(ctx context.Context) (pos ltx.Pos, err error) {\n\tinfo, err := r.MaxLTXFileInfo(ctx, 0)\n\tif err != nil {","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L240-L276","documentation":"This error occurs when Replica.uploadLTXFile fails to upload a local LTX file to the replica's storage backend via Client.WriteLTXFile. The local file was already opened successfully; the failure is in writing to remote storage. The wrapped error carries the underlying client cause (network, auth, quota, etc.).","triggerScenarios":"syncOnce (or an anonymous uploader goroutine) calls uploadLTXFile for a level/minTXID/maxTXID, the local LTX file opens fine, but r.Client.WriteLTXFile returns an error — network outage, expired cloud credentials, bucket missing, quota exceeded, or a partially-written local file.","commonSituations":"S3/GCS/Azure credentials expired or wrong; network partition between litestream and object storage; destination bucket deleted or permissions changed; disk returning truncated/corrupt LTX data.","solutions":["Read the wrapped cause from the message to identify the storage-client failure (auth, network, permissions).","Verify replica credentials and bucket/container exist and are writable.","Check network connectivity to the storage endpoint; retry after transient failures.","If local LTX state is suspect, run `litestream reset` for the database to rebuild local LTX files."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight storage write access\n_, err := client.WriteLTXFile(ctx, level, minTXID, maxTXID, bytes.NewReader(nil))\n// or verify credentials/bucket reachability before starting replication","typeGuard":null,"tryCatchPattern":"if err := replica.Sync(ctx); err != nil && strings.Contains(err.Error(), \"write ltx file\") {\n    // transient storage failure: backoff and retry; check wrapped cause for auth vs network\n}","preventionTips":["Rotate cloud credentials before expiry and test writes to the bucket","Monitor object-storage connectivity and error rates","Run `litestream reset` only after persistent local LTX corruption"],"tags":["replication","storage","upload","network"],"backgroundTag":"file-write-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"}