benbjohnson/litestream · critical

invalid replica, checksum mismatch

Error message

invalid replica, checksum mismatch

What it means

ErrChecksumMismatch indicates a replica LTX file's contents do not match its recorded checksum, so the replicated data cannot be trusted. It is wrapped in LTXError and marked auto-recoverable: with the auto-recover replica option enabled, litestream resets local state and re-syncs from the replica.

Source

Thrown at litestream.go:34

)

// 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 != "" {

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Run `litestream reset <db>` to clear corrupted local LTX state and re-sync from the replica
  2. Enable auto-recover: true on the replica so this resets automatically
  3. Delete the .sqlite-litestream directory and restart if reset is unavailable
  4. Investigate the storage backend for truncated or corrupted uploads

Example fix

# before (yaml)
replicas:
  - url: s3://bucket/db
# after
replicas:
  - url: s3://bucket/db
    auto-recover: true
Defensive patterns

Strategy: try-catch

Type guard

func isAutoRecoverableLTX(err error) bool {
    var le *litestream.LTXError
    return errors.As(err, &le) && le.IsAutoRecoverable()
}

Try / catch

if err := db.Sync(ctx); err != nil {
    var ltxErr *litestream.LTXError
    if errors.As(err, &ltxErr) && errors.Is(ltxErr.Err, litestream.ErrChecksumMismatch) {
        // reset local state and re-sync from replica
        return litestream.Reset(ctx, dbPath)
    }
    return err
}

Prevention

When it happens

Trigger: Decoded LTX data failing checksum verification during verify/apply operations; surfacing through NewLTXError and LTXError.IsAutoRecoverable (litestream.go:68) which returns true for it.

Common situations: Bit rot or truncated uploads in object storage, corrupted local .sqlite-litestream cache files, partial network reads persisted to disk, storage provider bugs.

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/e8b712600f671203. Report an issue: GitHub.