- Error number
- 7391
- Severity
- 16 (user-correctable error)
- State
- Not documented by Microsoft (not reproduced here)
- Product
- Microsoft SQL Server Database Engine
- Versions
- All supported SQL Server versions (2016 to 2025) on Windows with linked servers; on Linux, MSDTC must be configured separately
- Category
- Linked Servers
- Last reviewed
- 24 October 2026
On this page
What it means
Error 7391 means a statement needed to turn your transaction into a distributed transaction across a linked server, and the Microsoft Distributed Transaction Coordinator (MSDTC) on one of the servers could not start or join it.
When a transaction changes data on a linked server, or explicitly starts with BEGIN DISTRIBUTED TRANSACTION, SQL Server asks MSDTC to coordinate a two-phase commit between both servers. If the provider cannot enlist in that transaction, SQL Server stops with 7391. The quoted names are the provider and the linked server; the cause is almost never in the query itself.
Microsoft lists the usual reasons: MSDTC is not running, or it runs with network access switched off, on either server; the two servers cannot reach each other by name in both directions; a firewall blocks the RPC ports MSDTC uses; or the linked server loops back to the same instance, which does not support distributed transactions. A remote object can also call a third server, which then becomes the real source of the failure.
Common causes
- The MSDTC service is stopped, or Network DTC Access (inbound and outbound) is disabled, on the local or the remote server.
- Name resolution or a firewall blocks MSDTC: the servers can reach each other by IP address but not by name, or the dynamic RPC ports are closed.
- A local transaction is promoted because it changes remote data (or runs
INSERT ... EXECagainst a remote procedure) while the remote side cannot take part in a distributed transaction. - The provider or the remote data source does not support distributed transactions, or the linked server points back to the same instance (loopback).
- On a failover cluster, the clustered MSDTC resource or its name resolution is not configured correctly.
Diagnose it
Read-only These queries only read metadata and dynamic management views. They do not change data, permissions or configuration, so they are safe to run first.
Which provider and options does the linked server use?
SELECT name, provider, data_source, is_rpc_out_enabled,
is_remote_proc_transaction_promotion_enabled
FROM sys.servers
WHERE is_linked = 1; A data_source that names this same instance is a loopback, which Microsoft does not support for distributed transactions. is_remote_proc_transaction_promotion_enabled = 1 (the default) means remote procedure calls inside a local transaction are promoted to MSDTC.
Does the server name match the machine?
SELECT @@SERVERNAME AS server_name,
SERVERPROPERTY('MachineName') AS machine_name,
SERVERPROPERTY('ServerName') AS instance_name; Microsoft recommends checking that @@SERVERNAME matches the computer name on both servers. A mismatch (for example after a machine rename) can break the name resolution MSDTC relies on.
Is the server-wide remote proc trans option on?
SELECT name, value_in_use
FROM sys.configurations
WHERE name IN (N'remote proc trans', N'remote access'); With remote proc trans at 1, remote procedure calls always run inside a distributed transaction. It is 0 by default; if it is 1 here, that explains unexpected promotions.
Which distributed transactions are active now?
SELECT at.transaction_id, at.name, at.transaction_begin_time, at.dtc_state, st.session_id
FROM sys.dm_tran_active_transactions AS at
LEFT JOIN sys.dm_tran_session_transactions AS st ON st.transaction_id = at.transaction_id
WHERE at.transaction_type = 4 OR at.dtc_state <> 0; Rows show transactions enlisted in MSDTC. No rows while the error happens means the promotion failed at the start, which points at MSDTC or network configuration rather than at a stuck transaction.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Avoid the distributed transaction where you can
Client or network sideMicrosoft advises limiting a transaction that involves a distributed query to the remote server only. Often you can read remote rows into a local table first, outside the transaction, and then do the local changes in a local transaction; or run the remote change on its own with EXEC ... AT outside the local transaction.
-- Copy what you need first (no local transaction open)
SELECT order_id, total
INTO #remote_orders
FROM OPENQUERY(SALESSRV01, 'SELECT order_id, total FROM Sales.dbo.Orders WHERE order_date >= ''2026-10-01''');
BEGIN TRANSACTION;
UPDATE o SET o.total = r.total
FROM dbo.Orders AS o JOIN #remote_orders AS r ON r.order_id = o.order_id;
COMMIT;
Set XACT_ABORT ON for remote data changes
Client or network sideFor data modifications against most OLE DB providers, including SQL Server, inside an implicit or explicit transaction, Microsoft requires SET XACT_ABORT ON.
SET XACT_ABORT ON;
BEGIN DISTRIBUTED TRANSACTION;
UPDATE SALESSRV01.Sales.dbo.Orders SET status = 'shipped' WHERE order_id = 1001;
UPDATE dbo.Shipments SET shipped = 1 WHERE order_id = 1001;
COMMIT;
Start MSDTC and allow network transactions on both servers
Changes configurationOn each server, start the Distributed Transaction Coordinator service and, in Component Services (dcomcnfg), Local DTC Properties, Security, enable Network DTC Access with inbound and outbound transactions. Make sure both servers resolve each other by name in both directions and that the firewall allows MSDTC and its RPC ports.
Caution: These are Windows and network security settings on both machines. Agree them with the server and network owners and change them in a maintenance window.
Stop promoting remote procedure calls, if the call does not need to be transactional
Changes configurationIf a remote procedure call inside a local transaction does not need to commit or roll back with it, turn off promotion for that linked server only.
Caution: Without promotion the remote work is no longer rolled back with your local transaction. Only do this when that is acceptable.
EXEC master.dbo.sp_serveroption
@server = N'SALESSRV01',
@optname = N'remote proc transaction promotion', @optvalue = N'false';
Examples
Changing remote and local data in one transaction
Shown as documented by Microsoft; not reproduced here, because it needs two servers and an MSDTC that is stopped or closed to the network. The state is not documented, so no message header is shown. A loopback linked server on our test instance gave error 3910 instead (shown in the variants).
BEGIN TRANSACTION;
UPDATE SALESSRV01.Sales.dbo.Orders SET status = 'shipped' WHERE order_id = 1001;
UPDATE dbo.Shipments SET shipped = 1 WHERE order_id = 1001;
COMMIT;
The operation could not be performed because OLE DB provider "MSOLEDBSQL19" for linked server "SALESSRV01" was unable to begin a distributed transaction.
How to prevent it
Design cross-server work so that most of it does not need a distributed transaction: stage remote data locally, or let each server commit its own part with a retry or reconciliation step. Where a distributed transaction is truly needed, include MSDTC (service, Network DTC Access, firewall, name resolution in both directions) in the server build checklist for both sides, and test it after patching, cluster changes or firewall changes.
Common questions
Why does a SELECT from the linked server work but the UPDATE fails?
A read outside a transaction does not need MSDTC. A change to remote data inside a transaction must be coordinated with the local transaction, so it is promoted to a distributed transaction, and that is the step that fails.
Can I test distributed transactions with a linked server that points to the same instance?
No. Microsoft states that loopback linked servers are meant for testing and do not support distributed transactions. On our test instance such a loopback gave error 3910, not 7391.
Does 7391 mean the remote login is wrong?
Usually not. The connection itself works; it is the transaction coordination that fails. Login problems show up as 7416, 7399 or 18456 instead.
Learn more on CodeWithSQL
Official documentation
- MSSQLSERVER_7391 (Microsoft Learn)
- BEGIN DISTRIBUTED TRANSACTION (Transact-SQL)
- Error message of OLE DB provider when you run a linked server query
- sp_serveroption (Transact-SQL)
Last technically reviewed 24 October 2026; examples and diagnostics run on SQL Server 2025 (17.0.1145.4). Message text checked against the engine's sys.messages catalogue.