state_desc in sys.databases first, then compare sys.master_files paths against what is actually on disk. The database is almost always in RECOVERY_PENDING because a file it needs cannot be opened. Fix the file path or the file access, run ALTER DATABASE ... SET ONLINE, and it comes straight back.945 is a symptom, not the disease. Something stopped SQL Server opening one of the database’s files at startup, the database parked itself, and every connection that tries to use it gets this message instead. The three causes it names sit in strict order of likelihood: inaccessible files first by a distance, then disk space, then memory.
The whole error below was reproduced on a real instance while writing this, from breaking the database to bringing it back, so every message and state you see here is what the engine actually emits rather than what the documentation implies.
What the Instance Actually Looks Like
Two queries tell you nearly everything. The first is the state of the database, and with 945 it will almost certainly read RECOVERY_PENDING: SQL Server knows the database exists, cannot open its files, and has not even been able to begin recovery.
SELECT name, state_desc
FROM sys.databases
WHERE name = 'YourDb';
The second is where SQL Server believes the files are, which you then check against the disk by hand:
SELECT type_desc, physical_name
FROM sys.master_files
WHERE database_id = DB_ID('YourDb');
The error log fills in whichever detail the message left out. When I broke a database for this post by pointing it at a file that does not exist, the log carried the whole story in one chain: 5120 unable to open the physical file with operating system error 2, then 5181 could not restart the database, reverting to the previous status. The 945 you see in your session is the public face of that chain.
The Usual Suspects, In Order
| Cause | How it happens |
|---|---|
| The file moved or was renamed | A drive letter changed, a file was tidied into a new folder, a SAN volume came back under a different path, or a migration moved files without updating the database. SQL Server still holds the old path in sys.master_files and cannot know where the file went. |
| The engine lost permission | The file is exactly where it should be, but an ACL change, a restore from backup software, or a copy between machines stripped the SQL Server service account’s rights to it. You can see the file in Explorer; the service cannot open it. |
| The volume is not there yet | After a reboot, SQL Server can start before a mount point, iSCSI target or BitLocker-protected volume is available. Databases on that volume come up RECOVERY_PENDING and 945 until it appears. |
| Disk full or out of memory | The two causes the message names last, and the two you will meet least. The error log makes it obvious when either is genuinely the reason. |
The Fix, Measured
Once the file problem is solved, the database does not need restoring, rebuilding or detaching. It needs to be told to start again. In the reproduction for this post the repair was two statements: point the catalog back at the right file, then bring the database online.
-- Only needed if the path in sys.master_files is wrong:
ALTER DATABASE YourDb
MODIFY FILE (NAME = YourDb, FILENAME = 'D:\SQLData\YourDb.mdf');
ALTER DATABASE YourDb SET ONLINE;
If the path was right and the problem was access or an absent volume, fix that side instead: restore the service account’s rights on the folder, or bring the volume back, and then run the SET ONLINE. The database went from RECOVERY_PENDING to ONLINE the moment the file could be opened, with no recovery drama, because nothing about the data ever went wrong.
What Not To Do
- Do not detach the database to “reset” it. Detaching a database that cannot be opened throws away the catalog entry that tells you which file is missing, and a database that will not attach is a harder problem than a database that will not open.
- Do not restart the service as a first move. If the file is still inaccessible, you get the same state back plus an outage for every other database. Restarting only helps when the real cause was a volume that has since come back.
- Do not reach for RESTORE yet. Restoring over a database whose files are merely mispointed converts a two-statement fix into a recovery exercise. Prove the files are actually gone or damaged first; the 823/824 family is the signal for damage, 945 on its own is not.
Common Questions
Is RECOVERY_PENDING the same as SUSPECT?
The message mentions memory and disk space, but my disk is fine. Why say it?
Why does my error say Level 14 when the catalog says severity 16?
sys.messages at severity 16, and the engine raises it at Level 14 when a session hits it. Measured on SQL Server 2025 while writing this post.Can this happen to tempdb or master?
Related Scripts
- Get Database Health, the state check that surfaces RECOVERY_PENDING across every database at once
- Get Database File Details, every physical path the instance believes in, ready to compare against the disk
- Get Recent Error Log Entries, the fastest way to the 5120 chain behind a 945
Leave a Reply