Blog Post

MSDTC finding issues

Tuesday, April 10, 2018 3:10 AM

While running my application I get the following exception:

The MSDTC transaction manager was unable to pull the transaction from the source transaction manager due to communication problems 

Error Message:

System.Transactions.TransactionManagerCommunicationException : Communication with the underlying transaction manager has failed.
  ----> System.Runtime.InteropServices.COMException : The MSDTC transaction manager was unable to pull the transaction from the source transaction manager due to communication problems. Possible causes are: a firewall is present and it doesn't have an exception for the MSDTC process, the two machines cannot find each other by their NetBIOS names, or the support for network transactions is not enabled for one of the two transaction managers. (Exception from HRESULT: 0x8004D02B)


Exceptions Stack Trace:

   at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)
   at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
   at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
   at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
   at System.Transactions.Transaction.Promote()
   at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)
   at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
   at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
   at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover, Boolean isFirstTransparentAttempt, Boolean disableTnir)
   at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
   at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
   at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling)
   at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()


The process of resolution

1, Get it to work


 MSDTC Configuration

  • Open "component services" in both servers
    • Navigate to Local DTC (Component Services>Computers>My Compouter>Distributed Transactions)
      • Enable the following 
      • Network DTC Access
      • Allow Remote Clients
      • Allow Inbound 
      • Allow Outbound
      • No Authentication Required
      • Enable XA Transactions
      • Enable SNA LU 6.2 Transactions
      • DTC Logon Account: should be same default is NT Authority\Network Service
  • SQL and Source machine has to have same configuration

Firewall issues (this will eliminate this from the equation) :

  • Ensure the firewall is disabled on your SQL machine
  • Ensure the firewall is disabled on your Source machine
  • Cloud case 
    • If you are using cloud, ensure NSG are OPEN for the specific ports 135 + your MSDTC ports
    • If you have SQL and Source machine on different NSGs ensure the firewall is modified on both

Once you have done that and it still does not work, I would recommend to use this amazing tool to diagnose the issue.


2, Ensure the application is secure again

  • Ensure your firewall rules are restored in Cloud
  • Ensure you have enabled firewall on SQL machine
  • Ensure you have enabled firewall on source machine


Additional help I have found relevant


From Stack Overflow:

Also encountered this error even though the config, firewalls and netbios/dns were set up correctly. The two servers in the setup were clones of one another, so MSDTC on each server had the same CID value, which makes them not able to interoperate.

Here are some other things to think about when troubleshooting MSDTC 

The situation is described under Ensure that MSDTC is assigned a unique CID value

The MSDTC feature of the Windows operating system requires unique CID values to ensure that MSDTC functionality between computers works correctly. Disk duplicate images of Windows installations must have unique CID values or MSDTC functionality may be impaired. This can occur when using virtual hard disks to deploy an operating system to a virtual machine.

To determine if MSDTC CID values for computers that are running the Windows operating system are unique, check the values for the entries under the HKEY_CLASSES_ROOT\CID registry key on both computers. If these values are not unique for each computer then follow the steps in the section Consider reinstalling the Distributed Transaction Coordinator service if other troubleshooting steps are not successful to reinstall MSDTC on one of the computers, which will then generate unique MSDTC CID values for that computer and accommodate proper MSDTC operations.

To reset the CIDs on a Windows 2012 Server use the following Powershell script:

#View: CIDs (These must be different on all systems)
ls Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | select Name

#reinstall MSDTC to regenerate CIDs. 
msdtc -uninstall
sleep 5
msdtc -install
sleep 5
Set-Service msdtc -startuptype "auto"
#then reboot for changes to take effect

Ping the machine my its netbios name

The IP address in the DNS for the server is outdated (as said in error message: "two machines cannot find each other by their NetBIOS names"). You can check if this is the case by trying ping servername from one server to another in the command prompt. If the ping by name fails and ping by IP succeeds (or ping by name returns the wrong IP), than you should talk to the System Admins to take a look at DNS/DHCP.