0XC0220011

STATUS_FWP_INCOMPATIBLE_TXN (0XC0220011) - Read-Only Transaction Fix

This error hits when you try to write or modify data inside a read-only database transaction. Happens a lot in MS SQL Server or Azure SQL with snapshot isolation. The fix is to switch the transaction to read-write or move the operation outside the read-only scope.

When This Error Hits

You'll see STATUS_FWP_INCOMPATIBLE_TXN (0XC0220011) most often in a .NET application connecting to SQL Server or Azure SQL Database. The trigger is almost always the same: you've got a stored procedure or a block of code running inside a transaction marked as read-only — usually from snapshot isolation or an explicit SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED — and then you try to run an INSERT, UPDATE, or DELETE statement. Or maybe you're calling a function that writes to a temp table or logs something.

I've seen this dozens of times in ETL jobs, report generation scripts, and batch processes where someone wrapped a whole operation in a read-only transaction for performance reasons, forgetting that part of the code actually writes data.

Root Cause

SQL Server doesn't allow data modification inside a read-only transaction. That's it. The transaction context is set to read-only — either by the application code (like TransactionScope with IsolationLevel.ReadUncommitted) or by a session setting (SET TRANSACTION ISOLATION LEVEL READ ONLY). When the engine sees a write operation inside that context, it throws this error.

The culprit is often snapshot isolation in Azure SQL or SQL Server 2016+. You set ALLOW_SNAPSHOT_ISOLATION ON and then the default transaction becomes read-only unless you explicitly mark it as read-write.

Fix It — Step by Step

Step 1: Check the Transaction Isolation Level

Run this in SSMS or your query tool while the error is happening:

SELECT session_id, transaction_isolation_level 
FROM sys.dm_exec_sessions 
WHERE session_id = @@SPID;

A value of 5 means snapshot isolation (read-only). Other common values: 1 = ReadUncommitted, 2 = ReadCommitted, 3 = RepeatableRead, 4 = Serializable. If it's 5 or 1, you're in read-only territory.

Step 2: Change the Application Code

If you're using C# with TransactionScope, never assume the default. Always set the isolation level explicitly to write:

using (var scope = new TransactionScope(TransactionScopeOption.Required, 
    new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
{
    // Your write operations here
    scope.Complete();
}

Swap ReadCommitted for ReadUncommitted only if you're okay with dirty reads — but that's rare for writes.

Step 3: Move the Write Outside the Read-Only Transaction

This is the bluntest fix. If you have a stored procedure that does a read-only operation followed by a write, split it:

  • First call: a read-only query with snapshot isolation.
  • Second call: a separate write operation without any read-only isolation.

Example in T-SQL:

-- Read operation
SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
BEGIN TRANSACTION;
SELECT * FROM Orders WHERE OrderDate = '2024-01-01';
COMMIT;

-- Write operation
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
UPDATE Orders SET Status = 'Processed' WHERE OrderDate = '2024-01-01';
COMMIT;

This keeps the read fast and the write safe.

Step 4: Disable Snapshot Isolation Temporarily

Only do this if you're troubleshooting and it's a dev environment:

ALTER DATABASE YourDatabase SET ALLOW_SNAPSHOT_ISOLATION OFF;
ALTER DATABASE YourDatabase SET READ_COMMITTED_SNAPSHOT OFF;

Then test your app again. If the error goes away, you've confirmed the root cause. Turn it back on afterwards and fix the code instead.

Still Failing? Check These

  • Linked server queries — If your query writes to a remote server inside a local read-only transaction, SQL Server may still throw this. Break it into two separate transactions.
  • Temp table writes — Sometimes SELECT INTO #temp inside a read-only transaction triggers this. Use CREATE TABLE #temp first, then INSERT outside the transaction.
  • ORMs like Entity Framework — EF sometimes defaults to read-only transactions for certain queries. Check your DbContext configuration. Set Database.BeginTransaction(IsolationLevel.ReadCommitted) explicitly.

That's it. Nine times out of ten, the fix is changing the isolation level or splitting the transaction. Don't overthink it.

Related Errors in Database Errors
UnavailableException: Cannot achieve consistency level Cassandra Consistency Level Violation Fix: Write vs Read Fail 0X00001A3A Fixing ERROR_CURRENT_TRANSACTION_NOT_VALID (0X00001A3A) SQLITE_CORRUPT (11) or disk I/O error SQLite database disk image is malformed – quick fix 0X00001AB5 ERROR_TRANSACTION_REQUIRED_PROMOTION (0X00001AB5) 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.