- Error number
- 829
- Severity
- 21 (fatal: the connection ends; may indicate a serious problem)
- State
- 1
- Product
- Microsoft SQL Server Database Engine
- Versions
- All supported SQL Server versions (2016 to 2025)
- Category
- Corruption & Consistency
- Last reviewed
- 24 October 2026
On this page
What it means
Error 829 means a query touched a page that is in the middle of a page restore, which has not been finished yet, so SQL Server will not let anyone read it until the restore sequence is completed.
When you restore individual pages (usually pages damaged by an 824 or 823 error), SQL Server copies the old page from the full backup and marks it RestorePending until the log backups have brought it up to date. In the Enterprise edition the rest of the database stays online during this; any query that needs one of those pages fails with 829. The message names the database ID and the page as (file:page).
Severity 21 ends the query and closes the connection, as we saw in the lab. The page is not lost: the fix is to complete the restore sequence, not to repair. The phrase "may indicate disk corruption" is a reminder that the page was probably restored because it was damaged, so the storage that damaged it still needs attention.
Common causes
- A page restore was started (
RESTORE DATABASE ... PAGE = ... WITH NORECOVERY) and the log backups have not been restored yet, so the page is behind the rest of the database. - A restore sequence was abandoned midway, for example because a log backup in the chain was missing or the person running it stopped.
- Automated or scripted recovery started a page restore after an 823 or 824 error and did not finish it.
Diagnose it
Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.
Which database is it, and is it in the full recovery model?
SELECT database_id, name, state_desc, recovery_model_desc
FROM sys.databases
WHERE database_id = DB_ID(); -- or the database ID from the message The database named by the ID in the message. Page restore needs the FULL or BULK_LOGGED recovery model and an unbroken chain of log backups.
Which pages were recorded as damaged, restored or repaired?
SELECT DB_NAME(database_id) AS database_name, file_id, page_id,
event_type, error_count, last_update_date
FROM msdb.dbo.suspect_pages
ORDER BY last_update_date DESC; Event types 1 to 3 are pages that failed with 823 or 824 errors (the likely reason for the page restore); 4 is restored, 5 repaired by DBCC, 7 deallocated by DBCC.
Which backups are available to finish the sequence?
SELECT TOP (20) bs.database_name, bs.type, bs.backup_start_date,
bs.backup_finish_date, bs.first_lsn, bs.last_lsn, bmf.physical_device_name
FROM msdb.dbo.backupset AS bs
JOIN msdb.dbo.backupmediafamily AS bmf ON bmf.media_set_id = bs.media_set_id
WHERE bs.database_name = DB_NAME() -- or the database name
ORDER BY bs.backup_finish_date DESC; The full backup the page came from (type D) and every log backup (type L) after it, in LSN order. A gap between one log backup's last_lsn and the next one's first_lsn means the chain is broken.
What restores ran recently?
SELECT TOP (20) rh.destination_database_name, rh.restore_date, rh.restore_type,
rh.user_name, bs.type AS backup_type, bs.backup_finish_date
FROM msdb.dbo.restorehistory AS rh
JOIN msdb.dbo.backupset AS bs ON bs.backup_set_id = rh.backup_set_id
WHERE rh.destination_database_name = DB_NAME()
ORDER BY rh.restore_date DESC; Who started the page restore, when, and which backups have already been applied, so you know where to continue.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Finish the page restore sequence
Changes database stateRestore every log backup taken after the full backup WITH NORECOVERY, then back up the log once more and restore that last backup WITH RECOVERY. This brings the page up to date with the rest of the database and clears RestorePending. Then run DBCC CHECKDB.
Caution: Apply log backups in order and do not skip any. Run the restore from master (or another database), not from a connection that uses the database being restored.
-- after RESTORE DATABASE AppDb PAGE = '1:360' FROM DISK = N'D:\Backups\AppDb_full.bak' WITH NORECOVERY:
RESTORE LOG AppDb FROM DISK = N'D:\Backups\AppDb_log1.trn' WITH NORECOVERY;
-- ... every later log backup WITH NORECOVERY ...
BACKUP LOG AppDb TO DISK = N'D:\Backups\AppDb_tail.trn';
RESTORE LOG AppDb FROM DISK = N'D:\Backups\AppDb_tail.trn' WITH RECOVERY;
If the log chain is broken, restore the whole database
Changes database stateA page cannot be brought forward past a missing log backup. Restore the database from the most recent full backup and the log backups you do have, to a new name first if you want to compare, and decide with the data owner how to handle the work after the gap.
Caution: RESTORE with REPLACE overwrites the current database. Back up the tail of the log first (BACKUP LOG ... WITH NO_TRUNCATE if the database is damaged) so no committed work is lost.
Fix the storage that damaged the page
Client or network sideLook for the original 823, 824 or 825 errors in the error log and for disk, controller and driver errors in the Windows System log, and fix those, otherwise the next page will need restoring too. Keep PAGE_VERIFY CHECKSUM on.
Examples
Reading a page whose page restore has not been finished
Reproduced in a scratch database on SQL Server 2025 (Developer edition, which allows online page restore). The page and database IDs vary. The connection is closed after the error. Running the rest of the sequence (BACKUP LOG, then RESTORE LOG WITH RECOVERY) made the table readable again.
ALTER DATABASE AppDb SET RECOVERY FULL;
GO
CREATE TABLE dbo.Orders (OrderId int PRIMARY KEY, Note char(200) NOT NULL);
INSERT dbo.Orders VALUES (1, 'a'), (2, 'b');
DECLARE @bak nvarchar(4000) = CAST(SERVERPROPERTY('InstanceDefaultBackupPath') AS nvarchar(4000)) + N'\cws_errlab_full.bak';
BACKUP DATABASE AppDb TO DISK = @bak WITH INIT, CHECKSUM;
GO
-- start a page restore of the table's data page, and stop before the log backups
DECLARE @bak nvarchar(4000) = CAST(SERVERPROPERTY('InstanceDefaultBackupPath') AS nvarchar(4000)) + N'\cws_errlab_full.bak';
DECLARE @page nvarchar(20) = (SELECT TOP (1) CONCAT(allocated_page_file_id, ':', allocated_page_page_id)
FROM sys.dm_db_database_page_allocations(DB_ID(), OBJECT_ID(N'dbo.Orders'), NULL, NULL, 'DETAILED')
WHERE page_type_desc = N'DATA_PAGE');
USE master;
RESTORE DATABASE AppDb PAGE = @page FROM DISK = @bak WITH NORECOVERY;
GO
USE AppDb;
SELECT * FROM dbo.Orders;
Msg 829, Level 21, State 1, Line 2 Database ID 15, Page (1:360) is marked RestorePending, which may indicate disk corruption. To recover from this state, perform a restore.
Reproduced on SQL Server 2025 (17.0.1145.4), 23 October 2026.
How to prevent it
Write down and rehearse the full page restore procedure (page restore, every log backup, a final log backup and its restore WITH RECOVERY), and run it to the end in one go. Check that the log backup chain is complete before you start.
Treat the original page damage as a storage incident: monitor errors 823, 824 and 825 and new rows in msdb.dbo.suspect_pages, and keep CHECKSUM page verification and regular DBCC CHECKDB runs.
Common questions
Is the data on the RestorePending page lost?
No. The page holds the copy from the full backup and is waiting for the log backups that bring it up to date. Finish the restore sequence and it becomes readable again.
Can I use the rest of the database while a page is RestorePending?
In the Enterprise edition (and Developer), yes: online page restore keeps the database online and only queries that touch the restoring pages fail. In other editions page restore is offline.
Will DBCC CHECKDB clear the RestorePending state?
No. Only completing the restore clears it. Run CHECKDB afterwards to confirm the database is consistent.
Learn more on CodeWithSQL
Official documentation
- Restore pages (SQL Server)
- Manage the suspect_pages table
- Database engine events and errors (0 to 999)
Last technically reviewed 24 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.