benbjohnson/litestream · critical

ltx file corrupted

Error message

ltx file corrupted

What it means

ErrLTXCorrupted indicates an LTX file failed structural verification (ltx.Decoder.Verify) or its header could not be decoded, meaning the transaction file is unreadable or truncated. Like checksum mismatch it is auto-recoverable and wrapped in LTXError with a recovery hint.

Source

Thrown at litestream.go:35

// 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 discard corrupted local LTX state and recover from the replica
  2. Enable auto-recover: true on the replica config
  3. Check disk space (ErrDiskFull often precedes corruption)
  4. Delete the .sqlite-litestream directory and restart as a manual fallback

Example fix

# before
litestream run -config /etc/litestream.yml   # keeps failing on corrupt file
# after
litestream reset /path/to/db.sqlite
litestream run -config /etc/litestream.yml
Defensive patterns

Strategy: try-catch

Type guard

func isLTXCorruption(err error) bool {
    return errors.Is(err, litestream.ErrLTXCorrupted)
}

Try / catch

if err := db.Sync(ctx); err != nil {
    if errors.Is(err, litestream.ErrLTXCorrupted) {
        slog.Error("corrupt LTX detected; run 'litestream reset' or rely on auto-recover", "err", err)
        return litestream.Reset(ctx, dbPath)
    }
    return err
}

Prevention

When it happens

Trigger: db.go:634 dec.Verify() failing on an LTX file before applying it; db.go:1702 dec.DecodeHeader() failing during WAL apply — both wrap the underlying error with %w: %w into ErrLTXCorrupted.

Common situations: Disk full or I/O errors while writing LTX files, crashed process leaving truncated files, corrupted local .sqlite-litestream state, damaged objects in the replica storage.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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