benbjohnson/litestream · error
write ltx file: %w
Error message
write ltx file: %w
What it means
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.).
Source
Thrown at replica.go:258
r.syncWaiters.Add(1)
defer r.syncWaiters.Add(-1)
if err := r.syncSem.Acquire(ctx, 1); err != nil {
return fmt.Errorf("wait for replica sync: %w", context.Cause(ctx))
}
return nil
}
func (r *Replica) uploadLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID) (err error) {
filename := r.db.LTXPath(level, minTXID, maxTXID)
f, err := os.Open(filename)
if err != nil {
return NewLTXError("open", filename, level, uint64(minTXID), uint64(maxTXID), err)
}
defer func() { _ = f.Close() }()
info, err := r.Client.WriteLTXFile(ctx, level, minTXID, maxTXID, f)
if err != nil {
return fmt.Errorf("write ltx file: %w", err)
}
r.Logger().Debug("ltx file uploaded",
"level", info.Level,
"minTXID", info.MinTXID,
"maxTXID", info.MaxTXID,
"size", info.Size)
// Track current position
//replicaWALIndexGaugeVec.WithLabelValues(r.db.Path(), r.Name()).Set(float64(rd.Pos().Index))
//replicaWALOffsetGaugeVec.WithLabelValues(r.db.Path(), r.Name()).Set(float64(rd.Pos().Offset))
return nil
}
// calcPos returns the last position saved to the replica for level 0.
func (r *Replica) calcPos(ctx context.Context) (pos ltx.Pos, err error) {
info, err := r.MaxLTXFileInfo(ctx, 0)
if err != nil {View on GitHub (pinned to 4ed7a308f6)
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.
Defensive patterns
Strategy: retry
Validate before calling
// preflight storage write access _, err := client.WriteLTXFile(ctx, level, minTXID, maxTXID, bytes.NewReader(nil)) // or verify credentials/bucket reachability before starting replication
Try / catch
if err := replica.Sync(ctx); err != nil && strings.Contains(err.Error(), "write ltx file") {
// transient storage failure: backoff and retry; check wrapped cause for auth vs network
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- replica sync: %w
- fetch ltx files: %w
- cannot determine L%d max ltx file for %q: %w
- oss: upload to %s: %w
- list level %d ltx files: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/330deb6a8c67db7c.
Report an issue: GitHub.