benbjohnson/litestream · critical

integrity check failed: %s

Error message

integrity check failed: %s

What it means

The PRAGMA quick_check/integrity_check executed successfully but returned something other than 'ok', meaning the restored database is corrupt or inconsistent. RestoreV3 then deletes the output (and -wal/-shm) files and reports this error. This is a genuine data-integrity failure of the restored artifact.

Source

Thrown at replica.go:1358

	}
	defer func() { _ = db.Close() }()

	var pragma string
	switch mode {
	case IntegrityCheckQuick:
		pragma = "quick_check"
	case IntegrityCheckFull:
		pragma = "integrity_check"
	default:
		return fmt.Errorf("unsupported integrity check mode: %d", mode)
	}

	var result string
	if err := db.QueryRowContext(ctx, "PRAGMA "+pragma).Scan(&result); err != nil {
		return fmt.Errorf("integrity check: %w", err)
	}
	if result != "ok" {
		return fmt.Errorf("integrity check failed: %s", result)
	}

	// Clean up -shm and -wal files that SQLite may create during the PRAGMA.
	_ = os.Remove(dbPath + "-shm")
	_ = os.Remove(dbPath + "-wal")

	return nil
}

// findBestV3SnapshotForTimestamp returns the best v0.3.x snapshot for the given timestamp.
// Returns nil if no suitable snapshot exists.
func (r *Replica) findBestV3SnapshotForTimestamp(ctx context.Context, client ReplicaClientV3, timestamp time.Time) (*SnapshotInfoV3, error) {
	generations, err := client.GenerationsV3(ctx)
	if err != nil {
		return nil, fmt.Errorf("list v0.3.x generations: %w", err)
	}
	if len(generations) == 0 {
		return nil, nil

View on GitHub (pinned to 4ed7a308f6)

Solutions

  1. Read the returned message: it names the corruption (e.g. 'malformed database image at page N').
  2. Re-run the restore — a fresh download may fix a truncated transfer.
  3. Restore from an earlier or later snapshot/generation with intact WAL segments.
  4. Verify the replica objects' integrity (sizes/checksums) in the storage console.
  5. If the source DB is healthy, re-establish replication with litestream reset to produce a clean generation, then restore.

Example fix

// before
litestream restore -output db.sqlite /path/db   // same corrupt snapshot
// after
litestream restore -timestamp 2026-09-01T00:00:00Z -output db.sqlite /path/db
Defensive patterns

Strategy: fallback

Try / catch

if err := replica.Restore(ctx, opt); err != nil && strings.Contains(err.Error(), "integrity check failed") {
    // retry with an earlier timestamp/generation; keep output paths clean
}

Prevention

When it happens

Trigger: Restore/RestoreV3 with IntegrityCheckQuick or IntegrityCheckFull where the PRAGMA result string != "ok" — e.g. 'malformed database image', page checksum failures after an incomplete snapshot download or corrupt WAL replay.

Common situations: Storage backend returning truncated objects; bit-rot on the replica; a snapshot that was uploaded while the source DB was in an inconsistent state (legacy v0.3.x path); interrupting litestream mid-upload.

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