You're going about your day, and then a client calls: their app that talks to SQL Server and some external system—maybe a legacy ERP or a message queue—just threw XACT_E_RECOVERY_FAILED (0X8004D107). The exact message says the xa_recover call failed for the XA resource. This typically happens right after a server restart or a failover, when the Distributed Transaction Coordinator (MSDTC) tries to resolve pending transactions that were left in doubt.
I've seen this with a manufacturing client whose barcode scanner system used XA transactions to sync inventory between SQL Server and an old AS/400. Every time the SQL box rebooted, we'd get this error. The root cause? MSDTC couldn't reach the XA resource DLL—usually the vendor's transaction manager—during recovery. It's not a SQL Server problem; it's a communication and configuration problem between MSDTC and the XA resource.
Why This Happens
When SQL Server participates in a distributed transaction, it uses MSDTC to coordinate with other resource managers. XA is a standard protocol for this. During recovery, MSDTC asks each XA resource to replay its transaction log via xa_recover. If that call fails, you get this error. The usual culprits:
- The XA resource DLL isn't registered properly with MSDTC.
- Network ports blocked between MSDTC and the remote resource.
- MSDTC logs are corrupted or missing.
- The XA transaction manager is down or unreachable at that moment.
The Fix: Step by Step
Here's what I do, in order. Skip the first if it's not your situation.
- Check if the XA resource is even available. Ping the machine that hosts the XA transaction manager. If it's not up, that's your problem. Bring it up, then restart MSDTC.
- Restart MSDTC clean. Open a command prompt as admin and run:
net stop msdtc
net start msdtc
This clears transient issues. But it won't fix a broken registration.
- Verify XA resource registration. Open
Component Services(fromAdministrative Tools), go toComponent Services>Computers>My Computer>Distributed Transaction Coordinator>Local DTC. Right-click and chooseProperties. Go to theXA Transactionstab. Make sure the vendor's XA DLL is listed. If not, clickAddand point to the DLL. I've seen this get wiped after a Windows update. - Reboot after re-registering. Don't just restart MSDTC. A full reboot ensures the DLL loads fresh.
Still Failing? Check These
If it's still throwing 0X8004D107, it's almost always one of these:
- Firewall ports. MSDTC uses RPC dynamic ports (49152-65535). If you've locked those down, the recovery call can't get through. Temporarily open them for a test—if it works, you know.
- MSDTC logs. Corrupted logs cause this. Delete the logs in
%SystemRoot%\System32\MsDtc\Log(back them up first), then restart MSDTC. This forces a fresh recovery. - SQL Server's XA configuration. Check the
XACTsettings in SQL Server Config Manager. EnsureEnable XA transactionsis checked. I've seen a DBA disable it during a security audit and forget to re-enable.
One last thing: if you're using a third-party XA resource, check their support docs. Some need a specific version of MSDTC or a hotfix. I had a client whose Oracle XA DLL required a registry tweak on the Windows Server 2016 box. That's rare, but it happens.
That's it. This error is fixable in five minutes if it's a service or registration issue. If it's network or logs, expect to spend a bit more time. But you won't be rebuilding SQL Server—I promise.