Quick Answer for Advanced Users
Enable Network DTC Access in Component Services, set security to allow Inbound and Outbound, open TCP 135 and the dynamic DTC ports in Windows Firewall, then restart MSDTC.
Why This Error Happens
XACT_E_NETWORK_TX_DISABLED (0x8004D024) shows up when you're trying to run a distributed transaction across two servers or even two SQL Server instances, and the MSDTC (Microsoft Distributed Transaction Coordinator) service can't accept the network request. The culprit here is almost always a misconfiguration in MSDTC's security settings or a firewall blocking the RPC ports that DTC uses.
I've seen this exact error in production when someone sets up a linked server between SQL Server boxes but never touches MSDTC. They assume that because both servers are on the same domain, everything will just work. It won't. MSDTC is off by default for network transactions. You have to explicitly turn it on.
Another common scenario is after a Windows update. Nobody restarts MSDTC, the service gets into a weird state, and suddenly your app that's been running fine for months throws this. The fix is usually the same.
The Fix: Step-by-Step
These steps assume you're running Windows Server 2016 or newer, and SQL Server 2012 or later. The principle applies to older versions too, just the UI might look slightly different.
- Open Component Services. Press Win + R, type
dcomcnfg, hit Enter. This is the main console for all things DTC. - Navigate to DTC. Expand
Component Services→Computers→My Computer→Distributed Transaction Coordinator. Right-clickLocal DTCand selectProperties. - Enable Network DTC Access. In the Security tab, check the box for
Network DTC Access. Then check bothAllow InboundandAllow Outbound. If you're using mutual authentication (which you should be if on a domain), leave the defaultMutual Authentication Requiredselected. For workgroup environments, you might needNo Authentication Required, but that's a last resort. - Restart MSDTC. Open an elevated PowerShell or Command Prompt and run:
Alternatively, you can do this from Services.msc, but the command line is faster if you're doing this on multiple servers.net stop msdtc && net start msdtc - Open Firewall Ports. The tricky part is DTC uses a fixed port (135) for RPC, but then picks random high ports for the actual data. You need to allow both. On each server, run this in an elevated prompt:
For the dynamic ports, you have two options. The quick way is to allow the whole rangenetsh advfirewall firewall add rule name="MSDTC RPC" dir=in action=allow protocol=TCP localport=13549152-65535. The better way is to configure a fixed port for DTC (I'll show that in the alternative section below). If you're in a hurry, just open that range.
If That Doesn't Fix It
Sometimes you've done all that and the error persists. Here's what to try next.
Check MSDTC Service State
Open Services.msc and verify the Distributed Transaction Coordinator service is actually running. I've seen it stuck in a stopped state after a failed restart. Set it to Automatic if it isn't already.
Look at the Event Log
Open Event Viewer, go to Applications and Services Logs → Microsoft → Windows → MSDTC. Look for errors with event ID 4150 or 4181. These usually give you the exact reason DTC won't start a network transaction. Often it's a certificate issue if you're using mutual auth and the machine isn't properly joined to the domain.
Use a Fixed Port for DTC
DTC using dynamic ports is a pain for firewalls. Setting a fixed port removes that variable. In Component Services, right-click Local DTC → Properties → Transport tab. Click Set under Incoming and enter a port like 5000. Do the same for Outgoing. Then open that port in the firewall, restart MSDTC, and test again. This is a cleaner setup than opening 16,000 ports, and I've done it in several production environments.
After setting the fixed port, your firewall rule becomes:
netsh advfirewall firewall add rule name="MSDTC Fixed Port" dir=in action=allow protocol=TCP localport=5000Verify the Client Machine's DTC
Don't forget that the error can originate from the calling server, not just the target. If your app runs on a separate web server, that machine also needs MSDTC enabled and the same firewall ports open. I've spent too long debugging a linked server that worked from SSMS but not from the app server, and it came down to the app server's DTC being locked down.
Preventing This in the Future
Once you've got it working, you don't want to revisit this in six months. Here's how to keep it stable.
- Set a fixed DTC port and document it. I can't stress this enough. Dynamic ports are fine for small setups, but they cause intermittent failures when the firewall is strict.
- Monitor MSDTC health. Set up a scheduled task that runs
sc query msdtcand alerts you if the state isn'tRUNNING. It's saved my bacon more than once. - When applying Windows updates, always plan a rolling restart of MSDTC after the patch. Most updates don't touch it, but some do, and it's better to restart it preemptively than to get a 2 AM call.
- If you're in a high-security environment, think hard about whether you really need distributed transactions. Sometimes you can refactor the app to avoid them. But if you can't, keep DTC config in a GPO or a PowerShell script so you can redeploy it quickly.
That's the whole deal. This error is annoying, but it's almost always fixable in twenty minutes. If you've followed these steps and it still throws 0x8004D024, double-check that you're actually hitting the right server and that the linked server is configured with RPC OUT enabled. I've seen that misconfiguration cause the same error when DTC was fine.