benbjohnson/litestream · error

ltx file missing

Error message

ltx file missing

What it means

ErrLTXMissing indicates a required LTX file is absent from local state or the replica — typically the next transaction in the sequence. It is auto-recoverable: LTXError.IsAutoRecoverable returns true for it, and NewLTXError attaches a hint to run `litestream reset <db>`.

Source

Thrown at litestream.go:36

// Naming constants.
const (
	MetaDirSuffix = "-litestream"
)

// SQLite checkpoint modes.
const (
	CheckpointModePassive  = "PASSIVE"
	CheckpointModeFull     = "FULL"
	CheckpointModeRestart  = "RESTART"
	CheckpointModeTruncate = "TRUNCATE"
)

// Litestream errors.
var (
	ErrNoSnapshots      = errors.New("no snapshots available")
	ErrChecksumMismatch = errors.New("invalid replica, checksum mismatch")
	ErrLTXCorrupted     = errors.New("ltx file corrupted")
	ErrLTXMissing       = errors.New("ltx file missing")
	ErrDiskFull         = errors.New("disk full")
)

// LTXError provides detailed context for LTX file errors with recovery hints.
type LTXError struct {
	Op      string // Operation that failed (e.g., "open", "read", "validate")
	Path    string // File path
	Level   int    // LTX level (0 = L0, etc.)
	MinTXID uint64 // Minimum transaction ID
	MaxTXID uint64 // Maximum transaction ID
	Err     error  // Underlying error
	Hint    string // Recovery hint for users
}

func (e *LTXError) Error() string {
	if e.Path != "" {
		return e.Op + " ltx file " + e.Path + ": " + e.Err.Error()
	}

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Run `litestream reset <db>` to rebuild local state from the replica
  2. Enable auto-recover: true on the replica so resets happen automatically
  3. Avoid manual VACUUM/checkpoints on databases managed by litestream, or restart litestream after them
  4. Check storage lifecycle rules so objects are not deleted while still needed

Example fix

# before
sqlite3 db.sqlite 'VACUUM;'   # while litestream runs -> ErrLTXMissing
# after
litestream reset /path/to/db.sqlite && litestream run -config /etc/litestream.yml
Defensive patterns

Strategy: try-catch

Type guard

func isLTXMissing(err error) bool {
    return os.IsNotExist(err) || errors.Is(err, litestream.ErrLTXMissing)
}

Try / catch

if err := db.Sync(ctx); err != nil {
    if isLTXMissing(err) {
        // hint from NewLTXError: reset and recover from replica
        return litestream.Reset(ctx, dbPath)
    }
    return err
}

Prevention

When it happens

Trigger: Opening/applying the next LTX position when the file does not exist locally (os.IsNotExist) or errors.Is(err, ErrLTXMissing); common after VACUUM, manual checkpoints, or local state deletion out from under a running instance.

Common situations: Running VACUUM or manual SQLite checkpoints outside litestream which invalidate tracked positions, deleting part of .sqlite-litestream manually, retention/lifecycle rules removing objects still referenced locally.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06). Data as JSON: /api/errors/cc4fb4720ceac5c7. Report an issue: GitHub.