{"record":{"id":"4e9cbd0bb78ab793","repo":"benbjohnson/litestream","slug":"integrity-check-failed-s","errorCode":null,"errorMessage":"integrity check failed: %s","messagePattern":"integrity check failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"replica.go","lineNumber":1358,"sourceCode":"\t}\n\tdefer func() { _ = db.Close() }()\n\n\tvar pragma string\n\tswitch mode {\n\tcase IntegrityCheckQuick:\n\t\tpragma = \"quick_check\"\n\tcase IntegrityCheckFull:\n\t\tpragma = \"integrity_check\"\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported integrity check mode: %d\", mode)\n\t}\n\n\tvar result string\n\tif err := db.QueryRowContext(ctx, \"PRAGMA \"+pragma).Scan(&result); err != nil {\n\t\treturn fmt.Errorf(\"integrity check: %w\", err)\n\t}\n\tif result != \"ok\" {\n\t\treturn fmt.Errorf(\"integrity check failed: %s\", result)\n\t}\n\n\t// Clean up -shm and -wal files that SQLite may create during the PRAGMA.\n\t_ = os.Remove(dbPath + \"-shm\")\n\t_ = os.Remove(dbPath + \"-wal\")\n\n\treturn nil\n}\n\n// findBestV3SnapshotForTimestamp returns the best v0.3.x snapshot for the given timestamp.\n// Returns nil if no suitable snapshot exists.\nfunc (r *Replica) findBestV3SnapshotForTimestamp(ctx context.Context, client ReplicaClientV3, timestamp time.Time) (*SnapshotInfoV3, error) {\n\tgenerations, err := client.GenerationsV3(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"list v0.3.x generations: %w\", err)\n\t}\n\tif len(generations) == 0 {\n\t\treturn nil, nil","sourceCodeStart":1340,"sourceCodeEnd":1376,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/replica.go#L1340-L1376","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the returned message: it names the corruption (e.g. 'malformed database image at page N').","Re-run the restore — a fresh download may fix a truncated transfer.","Restore from an earlier or later snapshot/generation with intact WAL segments.","Verify the replica objects' integrity (sizes/checksums) in the storage console.","If the source DB is healthy, re-establish replication with litestream reset to produce a clean generation, then restore."],"exampleFix":"// before\nlitestream restore -output db.sqlite /path/db   // same corrupt snapshot\n// after\nlitestream restore -timestamp 2026-09-01T00:00:00Z -output db.sqlite /path/db","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := replica.Restore(ctx, opt); err != nil && strings.Contains(err.Error(), \"integrity check failed\") {\n    // retry with an earlier timestamp/generation; keep output paths clean\n}","preventionTips":["Run periodic test restores with IntegrityCheckFull to catch replica corruption early","Verify object sizes/checksums in storage after uploads","Never kill litestream mid-upload; use graceful shutdown","Keep multiple generations so you can fall back to an intact snapshot"],"tags":["sqlite","corruption","integrity-check","restore"],"backgroundTag":"checksum-mismatch","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}