Fix XACT_E_HEURISTICDANGER (0X8004D007) Quick Steps
This error means a DTC transaction ended in a heuristically dangerous state. You'll see it in MSDTC logs or event viewer. Here's how to clear it.
What is XACT_E_HEURISTICDANGER?
This error code 0X8004D007 comes from Microsoft Distributed Transaction Coordinator (MSDTC). It means a distributed transaction—one that spans multiple databases or systems—ended in a "heuristic" state. That's a fancy way of saying the transaction coordinator lost track of whether the transaction committed or aborted. Some parts might have committed, others might have rolled back. The system flags this as dangerous because data could be inconsistent.
You'll typically see this in SQL Server error logs, Windows Event Viewer under Applications and Services Logs > Microsoft > Windows > MSDTC, or in your application's exception output. It often happens after a network blip, a server restart mid-transaction, or a timeout during a two-phase commit.
Don't panic. This isn't a hardware failure. It's a state issue. You need to clean up the orphaned transaction. Below are three approaches. Start with the first one.
Fix 1: Check and Clear Pending Transactions (30 seconds)
Who this is for: If you're a developer or admin who can run a quick SQL query. This is the fastest fix if you know which database is involved.
- Open SQL Server Management Studio (SSMS). Connect to the server where the error appeared.
- Run this query to see if there are any pending distributed transactions:
ReplaceSELECT * FROM sys.dm_tran_database_transactions WHERE database_id = DB_ID('YourDatabaseName');YourDatabaseNamewith the actual name. - To list all open DTC transactions:
SELECT * FROM sys.dm_tran_active_transactions WHERE transaction_type = 4; -- 4 = distributed - If you see a transaction with a
dtc_stateof 2 (PREPARED) or 3 (PREPARED_COMMIT), you can force it to commit or roll back. But be careful—only do this if you know the transaction is safe to abandon. Use:KILL <transaction_id>; - After killing, check the error logs. The XACT_E_HEURISTICDANGER should disappear. If you still see it, move to Fix 2.
What you should see: After the kill, the transaction count drops in the view. The error in your application or log should stop firing.
Fix 2: Restart MSDTC Service (5 minutes)
Who this is for: When the database fix didn't work, or you can't identify the exact transaction. A restart clears the DTC's in-memory state.
- Open Services. Press Windows Key + R, type
services.msc, hit Enter. - Scroll down to Distributed Transaction Coordinator. Right-click it, select Stop.
- Wait 10 seconds. Right-click again, select Start.
- Now check if the error returns. If your application was mid-transaction when you restarted, you might see the error one more time as it resolves. That's normal. Wait 60 seconds and check logs.
Important: Restarting MSDTC doesn't delete transaction logs on disk. It only clears the service state. If the problem persists, you're probably dealing with a stuck transaction in the log file, which needs Fix 3.
What you should see: After restart, the Event Viewer should show MSDTC service started successfully (Event ID 4159). No new XACT_E_HEURISTICDANGER errors.
Fix 3: Clear MSDTC Transaction Logs (15+ minutes)
Who this is for: The error keeps coming back after a restart. This means the transaction is written to disk in the DTC log. You need to clean those logs.
WARNING: This will delete all pending DTC transactions. Any unresolved transactions will be lost. Only do this if you're sure no critical distributed transactions are in progress. Better to do this during a maintenance window.
- Stop the MSDTC service:
net stop msdtc - Open File Explorer. Navigate to
C:\Windows\System32\MSDTC. You might need to enable viewing hidden and system files. - Inside that folder, you'll see a subfolder named
TransactionsorTransdepending on your Windows version. Delete everything inside. Don't delete the folder itself, just the files. - Also check
C:\Windows\System32\Msdtc\MSDTC.LOG(it's a hidden file). Delete it if it exists. It will be recreated automatically. - Start MSDTC again:
net start msdtc - Verify the service is running:
You should seesc query msdtc | find "STATE"STATE : 4 RUNNING.
What you should see: After restarting, MSDTC creates a fresh log. Any pending transactions are gone. Your application should no longer throw XACT_E_HEURISTICDANGER. Check Event Viewer for MSDTC events. You should see Event ID 4096 (MSDTC started) and no errors.
One more thing: If you're on a cluster or using availability groups, don't do Fix 3 without checking cluster health. You'll want to move the MSDTC resource to another node first. But that's rare. For most single-server setups, this works.
Why this error happens in the real world: I've seen this most often when a SQL Server linked server query fails due to a network timeout while using distributed transactions. Another common trigger: a script that calls
BEGIN DISTRIBUTED TRANSACTIONbut never properly commits or rolls back after an error. The fix is almost always to kill the specific transaction (Fix 1) or clear the logs (Fix 3).
Was this solution helpful?