benbjohnson/litestream · error
new ltx encoder: %w
Error message
new ltx encoder: %w
What it means
ltx.NewEncoder failed when constructing the LTX encoder over the just-opened temp file. The temp file was opened successfully, so this typically indicates an invalid file descriptor state or an internal encoder initialization problem (the ltx package validates format parameters at construction). Replication for this transaction is aborted.
Source
Thrown at db.go:2144
}
defer func() { _ = os.Remove(tmpFilename) }()
defer func() { _ = ltxFile.Close() }()
uid, gid := internal.Fileinfo(db.fileInfo)
_ = os.Chown(tmpFilename, uid, gid)
db.Logger.Log(ctx, internal.LevelTrace, "encode header",
"txid", txID.String(),
"commit", commit,
"walOffset", info.offset,
"walSize", sz,
"salt1", rd.salt1,
"salt2", rd.salt2)
timestamp := time.Now()
enc, err := ltx.NewEncoder(ltxFile)
if err != nil {
return result, fmt.Errorf("new ltx encoder: %w", err)
}
if err := enc.EncodeHeader(ltx.Header{
Version: ltx.Version,
Flags: ltx.HeaderFlagNoChecksum,
PageSize: uint32(db.pageSize),
Commit: commit,
MinTXID: txID,
MaxTXID: txID,
Timestamp: timestamp.UnixMilli(),
WALOffset: info.offset,
WALSize: sz,
WALSalt1: rd.salt1,
WALSalt2: rd.salt2,
}); err != nil {
if isDiskFullError(err) {
return result, NewLTXError("stage-write", tmpFilename, 0, uint64(txID), uint64(txID), fmt.Errorf("%w: %w", ErrDiskFull, err))
}
return result, fmt.Errorf("encode ltx header: %w", err)View on GitHub (pinned to 4ed7a308f6)
Solutions
- Upgrade litestream to a matching release so the ltx package versions are consistent (go.mod / binary rebuild).
- Ensure nothing external touches files in the litestream data/staging directory while litestream is running.
- Use `litestream reset` to clear corrupted local LTX state for the database, then restart litestream.
- If reproducible, capture the underlying wrapped error and report it — NewEncoder failing on a fresh file usually indicates a bug.
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify matched litestream/ltx versions before rollout: // go list -m all | grep ltx && litestream version
Try / catch
if err != nil && strings.Contains(err.Error(), "new ltx encoder") {
log.Printf("encoder init failed; check ltx library version and staging dir: %v", err)
// escalate: likely bug or version mismatch, page on-call
} Prevention
- Keep litestream binary and ltx dependency from the same release
- Never let external tooling touch files in the litestream staging directory
- Pin the litestream version in deployment manifests
When it happens
Trigger: The os.File passed to ltx.NewEncoder is invalid or already errored (e.g. the underlying file was closed or removed concurrently), or the ltx library rejects construction arguments.
Common situations: External tooling deleting/rotating files in the litestream staging directory mid-sync; running mismatched litestream/ltx library versions after an incomplete upgrade; extremely constrained environments where the fd became unusable.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/9bbd49c19ffc17a7.
Report an issue: GitHub.