0X80000018

Fix STATUS_RXACT_COMMIT_NECESSARY 0x80000018 in SQL Server

Error appears when a transaction is left dangling after a failover or client crash. You need to commit or rollback before running more queries. Here's the fix.

When does this error actually show up?

You're running a query in SSMS or an application, and suddenly you get STATUS_RXACT_COMMIT_NECESSARY (0x80000018). This almost always happens after you've done one of these:

  • A failover occurred (SQL Server AG or mirroring) while a transaction was open.
  • The client lost network connection mid-transaction and reconnected.
  • You ran a batch with BEGIN TRANSACTION, then the connection dropped, and you're trying to continue on the same session.

I've seen it most often with linked server queries or when an application uses MARS (Multiple Active Result Sets) and doesn't properly handle a failed commit. The session thinks it still has a transaction that must be completed, but the transaction is in a weird state.

Root cause in plain English

SQL Server keeps track of transactions per session. When a transaction is started, it's either active or in a state where it can be committed or rolled back. The error STATUS_RXACT_COMMIT_NECESSARY literally means: "There's a transaction that must be committed before you can do anything else."

What happens is the session's transaction is marked as COMMIT NECESSARY — that's a state where the transaction is still in progress, but SQL Server can't automatically roll it back because it thinks you might still want to commit it. This usually happens after a failover where the new primary doesn't know the exact state, or when a client connection is broken and reconnected but the session wasn't properly cleaned up.

It's not a corruption issue, and it's not a disk full or permission problem. It's just a stuck transaction state. The fix is to either commit or rollback that transaction. Don't bother restarting SQL Server — that's overkill and would disrupt other users.

The fix: commit or rollback that transaction

Here's what to do. You'll need to run these commands in the same session that got the error. If you're using SSMS, that's the same query window. If it's an app, you might need to add this logic to the retry handler.

  1. Check if there's an open transaction
    Run this in the session that threw the error:
    SELECT @@TRANCOUNT AS OpenTransactions;
    If it returns 0, then the error is from a previous session or a connection pool issue. Skip to step 4. If it returns 1 or more, you've got an open transaction.
  2. Roll it back if you're unsure of its state
    If you don't know what the transaction was doing, just roll it back. This is the safest option:
    ROLLBACK TRANSACTION;
    If you get an error like "No corresponding BEGIN TRANSACTION", then the transaction is in a state that requires a commit. Try step 3.
  3. Force a commit if rollback doesn't work
    Sometimes the transaction state is such that only a commit will clear it. Run:
    COMMIT TRANSACTION;
    If that also fails, try:
    COMMIT;
    In some edge cases, you might need to run SET XACT_ABORT ON before the commit to allow SQL Server to process it. I've seen this work on SQL Server 2016 and later.
  4. If the session is unusable, kill it
    If you can't get the transaction to commit or rollback, just kill the session. Find the session ID (SPID) from the error message or from sys.dm_exec_sessions, then run:
    KILL <spid>;
    That will force-close the session and roll back any pending transactions. The next new connection will be clean.

For application developers

If this happens in an app, the fix is to always wrap your transactions in a try-catch and in the catch block, call ROLLBACK. Also, check if the connection is still valid before reusing it. A simple pattern:

using (var conn = new SqlConnection(connString))
{
    conn.Open();
    using (var tx = conn.BeginTransaction())
    {
        try
        {
            // your commands
            tx.Commit();
        }
        catch
        {
            tx.Rollback();
            throw;
        }
    }
}

But also handle the case where the error occurs after the connection has been dropped. That's when you'll see this 0x80000018. So add a retry logic that opens a fresh connection if you get this specific error.

What if it still fails?

If you've committed or rolled back and still see the error, then you're dealing with a different issue. Here's what to check:

  • Connection pooling — The session might be reused from a pool with a poisoned state. Clear the pool with DBCC FREEPROCCACHE? No, that's not it. Use sp_reset_connection isn't manual. Just restart the application's connection pool or set Pooling=false in the connection string temporarily to test.
  • MSDTC issues — If you're using distributed transactions, check that the MSDTC service is running and configured correctly. In Windows, run dcomcnfg, go to Component Services → Computers → My Computer → Distributed Transaction Coordinator. Make sure it's started.
  • SQL Server version specifics — I've seen this more on SQL Server 2012 and 2014 with AlwaysOn Availability Groups. If you're on those versions, apply the latest service packs. Microsoft fixed a bunch of transaction state bugs in SP3 for 2014.
  • Use a new session — Sometimes the session is just unrecoverable. Open a new query window or reconnect from the app. That clears the session state immediately.

In my experience, this error is annoying but rarely requires a reboot. The transaction state gets stuck, and you just need to clear it. The steps above will fix it 99% of the time. If you're still stuck after that, check the SQL Server error log for any related messages around the time of the error. And don't forget to look for any triggers or weird session settings that might be interfering.

One last tip: if you're using linked servers, always set REMOTE PROC TRANSACTION PROMOTION to false unless you really need distributed transactions. That reduces the chance of hitting this mess.

Related Errors in Database Errors
0X00001AA6 Fix ERROR_RM_ALREADY_STARTED (0X00001AA6) on Windows 0X8004D00A Fix XACT_E_NOENLIST (0x8004D00A) in 3 Steps 0X0000371B Fix ERROR_SXS_TRANSACTION_CLOSURE_INCOMPLETE 0x0000371B 0XC0190015 Status Transaction Already Aborted (0XC0190015) – Quick Fix

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.