Quick Answer
Restart the MSDTC service and clear the DTC log. If that doesn’t work, check for stale transaction contexts in your application code or rebind the COM+ component.
What’s Happening Here
This error pops up when a resource manager – typically SQL Server or a COM+ application – gets handed a transaction unit of work (UOW) that doesn’t match its own records. Think of it like a key that doesn’t fit the lock. The transaction was either already committed, rolled back, or never existed on that resource manager. I see this most often in three scenarios: after a DTC service crash, when a web app reuses a stale transaction object, or when two different DTC instances get crossed in a load-balanced setup.
Fix Steps
- Restart the MSDTC service. Run
net stop msdtc && net start msdtcas Administrator. This clears in-memory transaction state without touching the log file. Nine times out of ten, this alone fixes it temporarily. - Clear the DTC log file. If the error comes back after a restart, the log is corrupt. Stop MSDTC, delete the log, then restart. The log lives at
C:\Windows\System32\Msdtc\MSDTC.LOG. Run:
Windows recreates the log on restart. Only do this if you’re OK losing any pending distributed transactions (which you likely don’t have if you’re hitting this error).net stop msdtc cd %SystemRoot%\System32\Msdtc del MSDTC.LOG net start msdtc - Check DTC security settings. Open Component Services (dcomcnfg), go to Distributed Transaction Coordinator > Local DTC > Properties > Security. Enable Network DTC Access, Allow Remote Clients, Allow Inbound, and Allow Outbound. Apply and restart DTC. This fixes communication mismatches in cross-server transactions.
- Rebind COM+ components. If you’re using COM+ transactions, the component might have a stale reference. Use
regsvr32on the component DLL or reinstall the COM+ application. Runregsvr32 /u YourComponent.dllthenregsvr32 YourComponent.dll.
If That Doesn’t Work
Try these in order:
- Check for orphaned transactions in SQL Server. Run
SELECT * FROM sys.dm_tran_active_transactionsand look for open transactions with a NULL or stale UOW. Kill them withKILL <session_id>. - Review your application code. Don't cache TransactionScope objects. Create a new one per operation. In .NET, wrap it in a
usingblock and let it dispose naturally. - Update DTC to use a specific CID. Rare, but if you have multiple DTC instances, set the CID via registry:
HKLM\Software\Microsoft\MSDTC\CID. Set it to a unique GUID. Reboot.
Prevention Tips
- Always use
usingblocks or explicitDispose()calls for transaction objects. Leaked transactions = stale UOWs. - Monitor DTC log size. A log over 10 MB often signals corruption. Set a scheduled task to restart DTC weekly if you see it grow.
- In load-balanced web farms, use a single DTC instance or configure consistent routing. Crossed DTCs cause this error every time.
One last thing: don’t bother reinstalling Windows or the DTC role for this error. That’s like using a sledgehammer on a pushpin. The log clear and service restart handles 95% of cases.