Fix it now
8992 is the catalogue half of DBCC CHECKDB reporting that the system metadata tables no longer agree with each other. Microsoft states plainly that DBCC CHECKDB cannot repair this error and that the database must be restored from a backup. Your routes out are a restore, or moving the objects into a fresh database.
DBCC CHECKCATALOG (N'MyDb') WITH NO_INFOMSGS;
DBCC CHECKDB (N'MyDb') WITH NO_INFOMSGS, ALL_ERRORMSGS;
- Note every Msg 3852 and 3853 line. Each names the system view and the row that has no partner.
- Run the full CHECKDB as well, so you know whether pages are damaged too. Catalogue errors with page errors point at hardware.
- Restore from the newest backup that passes both checks after a test restore. That is the only route that keeps everything.
- If no clean backup exists, create a new empty database, script the schema out, and move the data across object by object.
Do not run REPAIR_ALLOW_DATA_LOSS expecting it to help. Microsoft’s own topic for 8992 says the error cannot be repaired, and the DBCC CHECKCATALOG reference repeats it: inconsistencies cannot be repaired and the database must be restored from a backup.
If the restored database passes both checks you are done. If you have no clean backup, the next section explains why there is nothing for repair to rebuild from.
Why it happens
The system catalogue is the database’s description of itself: which objects exist, which columns belong to them, which allocation units back which partitions. You read it through views such as sys.objects, sys.columns, sys.indexes and sys.partitions, but underneath it is a set of ordinary tables that only the engine may write. DBCC CHECKCATALOG walks the relationships between those tables and reports every one that does not hold.
Two detail messages accompany 8992 and they are worth reading rather than skimming. 3852 says a row in one system view has no matching row in the view that should describe it. 3853 says an attribute of such a row points at a row that does not exist. Both are severity 10, which is why they arrive looking like information rather than an alarm, and both name the exact views and identifiers involved.
When CHECKDB finds a damaged data page it can often rebuild the structure around it, because the same information exists in more than one place. Catalogue rows do not have that redundancy. If the row describing a column is gone, nothing else in the database knows what that column was. That is why Microsoft’s own words on this error are that DBCC CHECKDB cannot repair it, and that if you cannot restore from a backup you should contact Microsoft Support. Running repair on an 8992 costs you an outage and a single-user window for nothing.
A clean backup exists that predates the damage
You have this one if A full backup restores to a spare instance and passes both CHECKDB and CHECKCATALOG there.
- Restore the candidate to a test instance and run
DBCC CHECKDB (N'MyDb') WITH NO_INFOMSGS;andDBCC CHECKCATALOG (N'MyDb');before trusting it. - Take a tail-log backup of the damaged database if it is still online and in full recovery.
- Restore full, differential and log backups in order on the production instance.
- Run both checks again on the restored database before returning it to users.
Work backwards through your history. Catalogue damage is often weeks old before anyone notices, so the newest backup is frequently not the newest clean one.
No clean backup, but the objects are still readable
You have this one if CHECKCATALOG reports errors, yet applications query the tables normally and CHECKDB finds no page damage.
- Create a new empty database on the same instance.
- Script the schema out of the damaged database: right-click it in Object Explorer, then Tasks, then Generate Scripts. Run the result against the new database.
- Move the data with the Import and Export Wizard,
INSERT ... SELECTacross databases, or bcp for large tables. - Recreate logins, users, permissions and any SQL Agent jobs that referenced the old database.
- Rename or retire the damaged database once the application is verified against the new one.
Script out and copy, rather than detach and attach. Attaching the same files carries the same broken metadata into the new home.
An upgrade or patch left the metadata half-converted
You have this one if The errors appeared immediately after a version upgrade, a cumulative update, or attaching a database from an older instance.
- Read the SQL Server error log from the first startup after the change and look for upgrade scripts that reported failure.
- Confirm the compatibility level and the build:
SELECT name, compatibility_level FROM sys.databases;andSELECT SERVERPROPERTY('ProductVersion'), SERVERPROPERTY('ProductUpdateLevel'); - If the upgrade failed, restore the pre-upgrade backup, patch the instance completely, and repeat the upgrade.
- Re-run CHECKCATALOG once the instance is on a fully patched build.
Microsoft names one specific origin: running DBCC CHECKDB against a database that was upgraded from SQL Server 2000 to a later version. If that is the history of this file, it is the first thing to check.
DBCC will not process the database at all
You have this one if 8930 appears and DBCC stops, or the database sits in RECOVERY_PENDING or SUSPECT.
- Check the state first:
SELECT name, state_desc, is_read_only FROM sys.databases WHERE name = N'MyDb'; - Do not put the database into EMERGENCY mode as an opening move. Restore from backup if you have one.
- If there is no backup, take file-level copies of the MDF, NDF and LDF files with the instance stopped, so every attempt starts from the same point.
- 8930’s own message says the error cannot be repaired and to restore from a backup. Bring in help before attempting anything else.
Full reference
Where catalogue damage usually comes from
| Circumstance | What to check |
|---|---|
| System tables were updated directly | Historical allow-updates work, or changes made through the dedicated administrator connection. Microsoft names manual system table updates as a cause |
| The database was upgraded from SQL Server 2000 | Microsoft names this specifically as a circumstance in which CHECKDB reports 8992 |
| An upgrade or cumulative update failed part-way | The setup and error logs for a script that did not finish |
| The database was attached from another instance or version | Whether the upgrade scripts completed; check the error log for the attach |
| Underlying storage faults are also present | Run CHECKDB in full. Catalogue errors together with page errors point at hardware |
| The database was forced online out of EMERGENCY mode | Whether a previous repair or emergency recovery left the metadata half-built |
The reason many people have never run this check
DBCC CHECKDB runs CHECKCATALOG as part of its work, with one exception that matters: specifying TABLOCK stops it. Microsoft documents that TABLOCK limits the checks performed, that DBCC CHECKCATALOG is not run on the database, and that Service Broker data is not validated. A nightly maintenance job carrying TABLOCK to make the check finish faster has therefore never checked the catalogue, and catalogue damage in that estate will surface as a failed restore or a failed upgrade rather than as a nightly alert.
How CHECKCATALOG behaves when you run it directly
- Syntax is
DBCC CHECKCATALOG [ ( database_name | database_id | 0 ) ] [ WITH NO_INFOMSGS ]. Passing 0 means the current database. - The database must be online.
- It uses an internal database snapshot for transactional consistency, exactly as CHECKDB does.
- If the snapshot cannot be created it acquires an exclusive database lock instead, so it is not always non-blocking.
- Against tempdb it performs no checks at all, because snapshots are not available there.
- It does not check FILESTREAM data, which lives on the file system rather than in the database.
Deciding between a restore and a rebuild
| What you have | What to do |
|---|---|
| A backup that passes both checks on a test instance | Restore it. This is the only route that keeps everything, including permissions and object definitions |
| No clean backup, applications still working | Script out and copy into a new database. Slow, safe, and it leaves the damaged file untouched as a fallback |
| No clean backup, database will not come online | File-level copies first, then help. Once metadata is being edited, mistakes are not reversible |
| 8992 together with 823, 824 or page errors | Treat the storage as the primary problem. Fix that before restoring anything back onto it |
What not to try
Direct writes to system tables are unsupported and are the fastest way to turn a recoverable database into an unrecoverable one. Even where a mechanism exists to do it, using it puts the database outside support, and the row you invent will not carry the internal state the engine expects. If you get to the point of considering it, the honest options are a restore, a migration into a clean database, or Microsoft Support.
Equally, do not defer this indefinitely on the grounds that the application still works. Inconsistent metadata tends to surface later as a backup that fails, an upgrade that will not run, or a restore that stops half way. Plan the move into a clean database while the data is still readable and the choice is still yours.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
8992 |
Check Catalog Msg, Level, State: DBCC CHECKCATALOG or CHECKDB found an inconsistency in the system metadata tables. Microsoft states that DBCC CHECKDB cannot repair this error | Microsoft Learn |
3852 |
A row in one sys view does not have a matching row in the sys view that should describe it. Severity 10 | Microsoft Learn |
3853 |
An attribute of a row in one sys view does not have a matching row in another sys view. Severity 10 | Microsoft Learn |
8930 |
Database error: the database has inconsistent metadata. This error cannot be repaired and prevents further DBCC processing. Restore from a backup | Microsoft Learn |
Confirm the fix worked
- Run
DBCC CHECKCATALOG (N'MyDb') WITH NO_INFOMSGS;and confirm it returns nothing. - Run a full
DBCC CHECKDB (N'MyDb') WITH NO_INFOMSGS, ALL_ERRORMSGS;and confirm it is clean. - Take a full backup and confirm
RESTORE VERIFYONLYpasses against it. - If you migrated, compare object counts between the two databases:
SELECT type_desc, COUNT(*) FROM sys.objects GROUP BY type_desc; - Confirm your scheduled CHECKDB job does not specify TABLOCK, or the catalogue check will keep being skipped.
Questions people ask about this
Will REPAIR_ALLOW_DATA_LOSS clear an 8992?
No. Microsoft’s topic for this error says it cannot be repaired and that you should restore from a backup or contact Support, and the DBCC CHECKCATALOG reference says the same. Running repair costs you an outage and single-user mode for nothing, and it may deallocate data pages that were never the problem.
Does a newer version or a higher edition fix this?
Not by itself. Catalogue damage lives in your database file, not in the engine, so moving the same file to a newer instance carries the problem with it. Patching matters only when a failed upgrade caused the damage in the first place. There is nothing to buy here.
Can I edit the system tables to put the missing row back?
Direct writes to system tables are not supported and are the fastest way to turn a recoverable database into an unrecoverable one. Even where a mechanism exists, using it puts the database outside support.
My nightly CHECKDB has never reported this. Is that reassuring?
Only if the job does not use TABLOCK. Microsoft documents that TABLOCK stops CHECKDB running CHECKCATALOG at all, along with Service Broker validation. Check the job definition before you conclude the catalogue is healthy.
My application works fine. Can I ignore it?
You can defer it, not ignore it. Inconsistent metadata tends to surface later as a failed backup, a failed upgrade or a restore that will not complete. Plan the move into a clean database while the data is still readable.
