What Triggers This Error
You'll see this error when a distributed transaction across two or more systems fails to commit. Common scenario: a web app talking to SQL Server on another box, or a COM+ component calling a remote database. The error code 0x8004D002 is the Microsoft Distributed Transaction Coordinator (MSDTC) telling you something went wrong at the commit phase — and it can't tell you why. That's the frustrating part.
Quick Fix — 30 Seconds
Before you dig into configs, do this: restart the MSDTC service on all machines involved in the transaction. Seriously. Half the time this clears a transient state that blocks commits.
net stop msdtc && net start msdtc
Run that on the app server and the database server. Then retry the transaction. If it works, you're done. If not, move on.
Moderate Fix — 5 Minutes
The culprit here is almost always MSDTC security settings or firewall rules. Let's tackle both.
Check MSDTC Security Configuration
Open dcomcnfg (Component Services), go to Component Services > Computers > My Computer > Distributed Transaction Coordinator > Local DTC. Right-click Local DTC and select Properties. On the Security tab, make sure these are checked:
- Network DTC Access
- Allow Remote Clients
- Allow Inbound
- Allow Outbound
- Enable Transaction Internet Protocol (TIP) if you're using Web Services
Set the Authentication to Mutual Authentication Required unless you're on a domain with older systems — then use Incoming Caller Authentication. Don't bother with No Authentication, it's a security risk and rarely works.
Apply, restart MSDTC, and test.
Firewall Rules for MSDTC
MSDTC uses a range of TCP ports, not just one. By default it uses RPC dynamic ports (1024-5000), but that's a mess for firewalls. Best practice: set a fixed port range.
- Open Registry Editor:
regedit - Go to
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC - Create a DWORD: ServerTcpPort and set it to 5000 (decimal) — or any port you like
- Create another DWORD: PortRange and set it to 100 (gives you ports 5000-5100)
- Restart MSDTC
Then open those ports in Windows Firewall (both inbound and outbound) on both machines. Also open TCP 135 (RPC Endpoint Mapper). Here's the PowerShell for that:
New-NetFirewallRule -DisplayName "MSDTC Fixed Ports" -Direction Inbound -Protocol TCP -LocalPort 5000-5100 -Action Allow
New-NetFirewallRule -DisplayName "MSDTC RPC" -Direction Inbound -Protocol TCP -LocalPort 135 -Action Allow
# Repeat for Outbound
New-NetFirewallRule -DisplayName "MSDTC Outbound" -Direction Outbound -Protocol TCP -LocalPort 5000-5100 -Action Allow
Test again. If the error persists, go advanced.
Advanced Fix — 15+ Minutes
If you're still stuck, it's time to dig deeper. The transaction log or network layer is corrupting the commit. Skip the registry tweaks — they won't help here.
Enable MSDTC Tracing
MSDTC can log detailed info to a file. Useful when the error says "unknown reason".
- Open
dcomcnfgagain - Right-click Local DTC, select Properties
- Go to the Tracing tab
- Set Trace Level to Verbose
- Set Trace Output to Console and File
- Set the file path to something like
C:\MSDTClogs\msdtc.log - Click OK and restart MSDTC
Reproduce the error, then open the log file. Look for TXF or TM entries around the time of failure. Common patterns:
- ABORT_INDOUBT — the transaction manager couldn't decide. Usually a network timeout.
- COMMIT_FAILED with a specific resource manager GUID — that points to a specific app or database.
- No entries at all — MSDTC isn't even seeing the transaction. Check your app's connection string or COM+ configuration.
Check Transaction Timeout
Long-running transactions can timeout before commit. Default MSDTC timeout is 60 seconds. If your transaction takes longer, bump it up.
reg add "HKLM\SOFTWARE\Microsoft\MSDTC" /v "TransactionTimeout" /t REG_DWORD /d 120 /f
net stop msdtc && net start msdtc
Set it to 120 or 180 seconds. Don't go crazy — 300 seconds max. Longer timeouts just mask problems.
Network Connectivity Test
This sounds basic, but skip it and you'll waste hours. Test basic connectivity between all machines involved in the transaction. Use Test-NetConnection or telnet to check port 135 and the fixed port range.
Test-NetConnection -ComputerName SQLServer1 -Port 135
Test-NetConnection -ComputerName SQLServer1 -Port 5000
If those fail, your firewall or network team is blocking the ports. Escalate to them with the port list from the moderate fix section.
Rebuild MSDTC
As a last resort, uninstall and reinstall MSDTC. This is rare, but I've seen corrupted registry keys survive a normal service restart.
msdtc -uninstall
msdtc -install
Run each command, then restart the machine. Reapply your security config and port settings. This wipes all MSDTC state, including any corrupted transaction log.
Wrap Up
Most of the time, the quick restart or the security config change resolves this. The error is vague by design — Microsoft doesn't expose the root cause in the error message because it's usually network or configuration related. Stick with the sequence above, and you'll get it sorted. If you're still stuck after the advanced steps, check your application logs for any Event ID 4099 or 4103 — those give more specific clues about which resource manager failed.