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
1452 (23000) MySQL 'Cannot add or update a child row: a foreign key constraint fails' fix ERROR: syntax error at or near end of input Fix SQL Syntax Error Near Unexpected End of Input 823 Fix SQL Server Index Corruption Error 823 ORA-00942 Fix ORA-00942: Table or View Does Not Exist Instantly

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.