A mailbox database that refuses to mount takes every mailbox on it offline, and the error in the shell is famously unhelpful. The database header, however, tells you exactly what Exchange is missing. In this post I'll show how to decode the mount error, read eseutil /mh, bring the database to a consistent state with soft recovery, and choose between reseed, restore and hard repair when that isn't possible.
Errors this guide fixes
MapiExceptionDatabaseError: Unable to mount database. (hr=0x80004005, ec=1108)Mount-Database / EACAn Active Manager operation failed. Error: The database action failed.Mount-Database / EACMapiExceptionJetErrorMissingLogFile: Unable to mount database. (hr=0x80004005, ec=-528)Mount-DatabaseState: Dirty Shutdowneseutil /mh+1 more guideCouldn't mount the database that you specified.Exchange admin center (EAC)-550 JET_errDatabaseDirtyShutdowneseutil / Application log (ESE)-1216 JET_errAttachedDatabaseMismatcheseutil / Application log (ESE)-501 JET_errLogFileCorrupteseutil / Application log (ESE)
Symptoms#
Mount-Database (or Servers › Databases › Mount in the Exchange admin center) fails with a message like this:
Failed to mount database "DB01". Error: An Active Manager operation failed. Error: The database action failed. Error: Operation failed with message: MapiExceptionDatabaseError: Unable to mount database. (hr=0x80004005, ec=1108)Admins report that the Exchange admin center version of the message starts with Couldn't mount the database that you specified., and that the underlying engine error is sometimes named instead, for example MapiExceptionJetErrorMissingLogFile: Unable to mount database. (hr=0x80004005, ec=-528) when a log file is missing. Dumping the database header shows State: Dirty Shutdown, and the Application log holds ESE, ExchangeStoreDB and MSExchangeRepl errors from the time of the mount attempt.
Tip: ec=1108 is generic. Look in the diagnostic context for StoreEc values that start with 0xFFFF — they are negative ESE error codes. Type the value into PowerShell to decode it: 0xFFFFFE0B returns -501, a corrupt log file.
Why it happens#
Exchange's database engine (ESE) uses write-ahead logging: every change goes to a transaction log first and into the .edb file later. If the database stops without flushing everything — a crash, power loss, a full log volume, a killed process — the header stays in Dirty Shutdown and records which log generations are needed to finish the job. On the next mount ESE replays those logs automatically. You only get the error when that replay can't happen:
| ESE error | Meaning | Usual cause |
|---|---|---|
-550 JET_errDatabaseDirtyShutdown | Recovery must run before the database can be used | Required logs weren't replayed |
-528 JET_errMissingLogFile | The current log file (E01.log for prefix E01) is missing | Logs deleted by hand, quarantined by antivirus or lost with a volume |
-501 JET_errLogFileCorrupt | A log file is damaged | Storage fault, crash while writing |
-1216 JET_errAttachedDatabaseMismatch | The logs expect a database attachment that's missing or doesn't match the database file | Wrong log folder, or an .edb replaced or restored without its matching logs |
-1018 JET_errReadVerifyFailure | Page checksum failure | Storage corruption — see JET error -1018 |
A full log volume is a very common trigger; if that's your situation, fix the space problem first with transaction logs filling the disk.
How to fix it#
1. In a DAG, switch copies instead of repairing#
If another copy is healthy, activate it and reseed the broken one later. That's faster and loses nothing:
Get-MailboxDatabaseCopyStatus DB01\* | Format-Table Name, Status, CopyQueueLength, ReplayQueueLength
Move-ActiveMailboxDatabase DB01 -ActivateOnServer EX02Never run eseutil recovery against a passive copy.
2. Protect what you have#
Leave the database dismounted and copy the .edb file, the whole log folder and the checkpoint (.chk) file to another volume before you change anything. Find the paths and the log prefix with:
Get-MailboxDatabase DB01 | Format-List Server, EdbFilePath, LogFolderPath, LogFilePrefix3. Read the database header#
From an elevated prompt on the server (eseutil.exe lives in %ExchangeInstallPath%Bin):
eseutil /mh "D:\DB01\DB01.edb"The lines that matter:
State: Dirty Shutdown
Log Required: 5873-5875 (0x16f1-0x16f3)
Repair Count: 0Log generations map to file names as the prefix plus eight hex digits, so with prefix E01 you need E01000016F1.log to E01000016F3.log. A consistent database shows State: Clean Shutdown and Log Required: 0-0.
4. Check that the required logs exist and are readable#
cd /d "E:\Logs\DB01"
eseutil /ml E01This checks the log set for prefix E01 and should end with Operation completed successfully. If a required log is missing, look in your antivirus quarantine, the backup software and any folder someone moved files into, and put it back.
5. Fix the cause, then let Exchange recover#
Free space on the log volume, add the antivirus exclusions and clear storage errors first. With the required logs in place, simply run Mount-Database DB01 again — ESE replays the logs as part of the mount.
6. Run soft recovery manually#
If the mount still fails, run recovery yourself; the output is far more specific than the shell error:
eseutil /r E01 /l "E:\Logs\DB01" /s "E:\Logs\DB01" /d "D:\DB01"/r takes the log prefix, /l the log folder, /s the checkpoint folder and /d the database folder. Soft recovery only replays logs; it doesn't throw data away. When it finishes, run eseutil /mh again and mount.
7. When the logs are gone for good#
- Restore the database from an Exchange-aware backup and let it replay the surviving logs. For selective recovery, restore into a recovery database (
New-MailboxDatabase -Recovery) and useNew-MailboxRestoreRequest. Dial-tone recovery — re-homing users to an empty database withSet-Mailbox -Database— keeps mail flowing while you restore. - Hard repair with
eseutil /ponly as the last resort, and on a copy. It discards whatever it can't read, so data loss is expected, and it asks you to confirm exactly that. Afterwards move the old logs and checkpoint aside, mount, runNew-MailboxRepairRequest -Database DB01 -CorruptionType SearchFolder,AggregateCounts,ProvisionedFolder,FolderView, and move every mailbox to a new database. Microsoft's support policy for repaired databases, published by the Exchange team in 2015, expects a database with aRepair Countabove zero to be evacuated.
Verify the fix#
eseutil /mhshowsState: Clean Shutdownbefore you mount.Get-MailboxDatabase DB01 -Status | Format-List Name, MountedreturnsMounted : True.Test-MAPIConnectivity -Database DB01reportsSuccess, and a user can open their mailbox.- In a DAG,
Get-MailboxDatabaseCopyStatus DB01\*shows one Mounted copy and the others Healthy. - A full backup completes, giving you a fresh recovery point.
Prevent it next time#
- Never delete transaction logs by hand; let backups or circular logging truncate them.
- Exclude the database and log folders from file-level antivirus scanning.
- Keep the log volume well away from full and alert on free space.
- Run more than one database copy in a DAG so a damaged copy means a reseed, not an outage — and use maintenance mode when patching.
- Test restores, not just backups.

