Database Cannot Be Opened Due to Inaccessible Files (Error 945)

🚨Part of the SQL Server Errors series, the exact messages and what actually causes them.

Msg 945  ·  Level 14  ·  State 2
Database ‘t945’ cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server errorlog for details.
Check 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

CauseHow it happens
The file moved or was renamedA 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 permissionThe 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 yetAfter 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 memoryThe 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?
No, and the difference decides how worried to be. RECOVERY_PENDING means recovery has not started because a file cannot be opened; fix the file and the database usually comes back untouched. SUSPECT means recovery ran and failed, which is a genuinely harder situation. 945 belongs to the first world.
The message mentions memory and disk space, but my disk is fine. Why say it?
The message text covers every reason the open can fail and cannot know which one applied. The error log can: it records the specific operating system error, and in the reproduction for this post that was error 2, file not found. Read the log before acting on any of the three causes.
Why does my error say Level 14 when the catalog says severity 16?
Both are real. The template sits in 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?
The system databases play by harsher rules: if master cannot open, the instance does not start at all, and tempdb is recreated at startup so a bad tempdb path also stops the service. 945 as a running-instance message is a user database story.

Related Scripts

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *