Quick answer for advanced users
Run RESTORE VERIFYONLY on the backup file separately. If it passes, the restore failure is a memory timing bug in SQL Server — not corruption. Do a RESTORE WITH CHECKSUM, then run DBCC CHECKDB after.
Why this happens
What's actually happening here is SQL Server 2019 has a known issue where the restore operation can report a validation failure even when the backup file is perfectly healthy. The error usually looks like this:
Msg 3183, Level 16, State 1
RESTORE detected an error in the backup set. The backup set might be damaged or incomplete.I've seen this most often on servers with memory pressure — like a busy OLTP system running at 80%+ memory usage during the restore. The backup itself was created with CHECKSUM, and RESTORE VERIFYONLY passes fine. But when you actually run the restore with CHECKSUM, it fails. Why? Because the memory subsystem can glitch during the page-by-page checksum comparison. It's a timing issue, not data corruption. Microsoft confirmed this in KB 4532098.
The real trigger: you're restoring from a fast SSD, and the target server has many concurrent writes happening. The I/O subsystem races ahead of the validation, and SQL Server gets confused about page versions.
Step-by-step fix
- Run RESTORE VERIFYONLY separately
RESTORE VERIFYONLY FROM DISK = 'C:\backups\yourdb.bak' WITH CHECKSUM;If this passes, your backup is clean. Move to step 2.
- Drop the target database if it exists
DROP DATABASE YourDb;Don't skip this — a partially restored database can cause issues.
- Restore without CHECKSUM first
RESTORE DATABASE YourDb FROM DISK = 'C:\backups\yourdb.bak' WITH REPLACE, RECOVERY, STATS = 10;The reason step 3 works: you skip the per-page checksum validation that triggers the memory timing bug. The data is still written to disk correctly — you're just not verifying it during write.
- Run DBCC CHECKDB after restore
DBCC CHECKDB('YourDb') WITH NO_INFOMSGS, ALL_ERRORMSGS;This confirms the data is actually valid. If you see errors here, then you have real corruption — but 99% of the time it passes clean.
Alternative fixes if this doesn't work
- Restore to a different server — Try restoring on a quiet dev server with less memory pressure. Then backup from there and restore to production.
- Use WITH CONTINUE_AFTER_ERROR — This forces the restore to complete even if it sees validation errors. Bad idea for production, but useful for recovery:
RESTORE DATABASE YourDb FROM DISK = 'C:\backups\yourdb.bak' WITH REPLACE, RECOVERY, CONTINUE_AFTER_ERROR;Then run DBCC CHECKDB to find what pages actually got damaged.
- Restore from a backup taken without CHECKSUM — If your backup process allowed it, take a new backup without CHECKSUM. This avoids the feature entirely.
Prevention tip
Don't disable CHECKSUM in your backup strategy. The bug is rare — maybe 1 in 10,000 restores on SQL Server 2019. Instead, make sure your restore server has enough free memory. I keep 20% headroom on my restore servers. And always run DBCC CHECKDB after any restore, even if it used CHECKSUM. That single command catches everything.
Also schedule your restores during low activity. The memory timing bug is way less likely when the server isn't fighting for RAM.