You're staring at 0X8004D10E and your transaction just died mid-flight — annoying, but the fix is usually a five-minute job.
The fix
Restart the Distributed Transaction Coordinator service on every machine that's part of the transaction. That's the machine running your app, the machine running SQL Server, and any middle-tier boxes in between. If it's a two-node cluster, do both nodes.
net stop msdtc
net start msdtc
Or if you'd rather not drop into an admin prompt:
Restart-Service MSDTC -Force
Then verify the service actually came back clean:
sc query msdtc
You want STATE : 4 RUNNING. If it's stuck in START_PENDING, the DTC log file is probably corrupt — jump to the "Log corruption" section below.
After the restart, retry the operation that failed. Nine times out of ten it goes through.
If it doesn't, open Component Services (dcomcnfg), drill into Component Services → Computers → My Computer → Distributed Transaction Coordinator → Local DTC, right-click Properties, and check the Security tab. Make sure "Network DTC Access" is ticked, "Allow Inbound" and "Allow Outbound" are both on, and the authentication mode matches what your app expects (Mutual Authentication Required is the safe default on Server 2016+). If you changed anything, restart MSDTC again.
Why this works
What's actually happening here is the DTC log manager on one machine decided the connection to its counterpart on another machine was gone. XACT_E_LU_DOWN literally means "log unit down" — the LU here is the DTC log unit, the component that owns the transaction log and coordinates two-phase commit across resources.
DTC doesn't tolerate a dropped LU connection gracefully. The moment the heartbeat between two DTC instances times out, the local one marks the remote LU as down and refuses to enlist it again until you restart the service. It won't auto-reconnect. That's a deliberate design choice: if the log manager is unreachable, DTC has no way to know whether the remote side already committed or rolled back, so it fails hard rather than risk a half-committed transaction.
The reason step 3 works is that stopping MSDTC forces a clean teardown of all LU bindings, and starting it rebuilds them from scratch. The new instance re-negotiates the RPC endpoint, re-registers with the cluster if applicable, and re-establishes the LU heartbeat. Old, stale bindings get thrown away.
Things that trigger this in the real world
- A network blip between your app server and your SQL box — a switch reboot, a VM live migration, a firewall rule that got pushed mid-day.
- The remote DTC service restarted (Windows Update, someone's "quick fix") while your transaction was in flight.
- Cluster failover where the DTC resource moved but the client still has the old node's endpoint cached.
- Kerberos ticket expiry on a long-running transaction — the LU connection re-authenticates and fails.
Less common variations
Log file corruption
If MSDTC refuses to start at all after the restart, the log at %SystemRoot%\System32\MsDtc\MSDTC.LOG is probably damaged. Reset it:
msdtc -resetlog
net start msdtc
Be aware: this discards in-doubt transactions. If you have any, resolve them first with msdtc -tmList and msdtc -tmResolve.
Firewall blocking the RPC dynamic port range
DTC uses RPC, and RPC uses a random high port unless you pin it. On Windows Server 2008 R2 and later, you can pin the port:
netsh int ipv4 set dynamicport tcp start=50000 num=1000
Then open that range on both sides. Also make sure TCP 135 and the DTC endpoint mapper are reachable — RPC won't even start negotiating without them.
Cluster name isn't resolvable
On a failover cluster, the DTC resource publishes a network name. If DNS isn't resolving that name to the current active node, every LU lookup fails. Check with nslookup and flush DNS if it's stale.
Antivirus real-time scanning on MSDTC folders
I've seen Symantec and older McAfee builds lock MSDTC.LOG during a transaction and cause exactly this error. Exclude %SystemRoot%\System32\MsDtc from real-time scanning. That one's under-documented but very real.
Preventing it
- Keep MSDTC patched. Several fixes for LU reconnect behavior shipped in Server 2016 and 2019 cumulative updates.
- Pin the RPC port range on every machine in the transaction path — random ports are firewall bait.
- Reduce transaction duration. Long-running transactions are the ones that die on a ticket expiry or a network hiccup.
- If you're on a cluster, make sure the DTC resource has a proper dependency on the network name and IP address, otherwise it comes up before the network does.
- Monitor the DTC event log (Applications and Services Logs → Microsoft → Windows → DistributedCOM) for LU reconnect warnings before users hit them.
Nine times out of ten the restart fixes it. The tenth time, it's DNS, a firewall, or antivirus — and now you know where to look.