Monday, March 2, 2026

SESSION_CONTEXT: Three Years, Two Bugs, One Workaround

If you use SESSION_CONTEXT() in any query that can run with parallelism, you may be getting wrong results right now and not know it. This is not new. It has been a documented known issue since January 2022. It shipped unfixed in SQL Server 2019, 2022, and 2025 — and as of 2025 CU2 (February 12, 2026), it is still not resolved.

This is easy to miss. It's buried in the Known Issues section of CU release notes, and the symptoms — wrong results or dump files — do not obviously point back to SESSION_CONTEXT.

What the Bug Does

Queries that call the built-in SESSION_CONTEXT function can return incorrect results when they execute with parallel plans. The issue is how SESSION_CONTEXT interacts with parallel execution threads — specifically when the session is reset for connection pool reuse. Parallel threads read the session context, but under certain conditions the value is not properly propagated across all threads. Some threads see it, others don't. The query completes without error. The results are just wrong.

Microsoft's own SESSION_CONTEXT documentation describes it this way:

Known Issues:

An Access Violation (AV) exception might occur with the SESSION_CONTEXT function 
under certain conditions. You might encounter AV exceptions or wrong results when 
the SESSION_CONTEXT function runs within a parallel execution plan when the session 
is reset for reuse.

Date discovered: January 2022
Status:          Has workaround
Date resolved:   (blank)

There are two failure modes:

Failure Cause
Wrong results Original bug. Parallel threads do not all receive the session context value.
Access violation dumps The fix for wrong results (introduced in 2019 CU14) causes AV dump files when the session is reset for reuse.

You either get wrong data or crash dumps. Pick your poison.

Why This Is Dangerous

SESSION_CONTEXT is not obscure. It is Microsoft's recommended mechanism for passing application context into SQL Server. If your application calls sp_set_session_context to set a TenantID or any other value — and your queries filter on that value — you are potentially at risk.

Common patterns that use SESSION_CONTEXT:

Row-Level Security (RLS) — security predicates that filter rows by SESSION_CONTEXT(N'TenantID')

Multi-tenant data isolation — WHERE clauses filtering on session-injected tenant or org identifiers

Audit context — triggers or views that stamp SESSION_CONTEXT(N'UserID') into audit columns

The danger is that this failure is silent. No error message. No warning. The query completes successfully. It just returns rows that belong to another user — or excludes rows that should have been included. You would only catch it if you validated the result set, and most applications do not validate what the database returns from a SELECT.

Where It Lives

This is listed as a known issue on every cumulative update from SQL Server 2019 CU14 (November 2021) through SQL Server 2025 CU2 (February 2026). Three major versions. Over three years.

Version CU Range Status
SQL Server 2019 CU14 – CU31 Known issue with workaround
SQL Server 2022 CU1 – CU23 Known issue with workaround
SQL Server 2025 RTM – CU2 Known issue with workaround

Sources: SQL Server 2025 CU2 (KB5075211), SQL Server 2022 CU23 (KB5078297), SQL Server 2019 CU14.

The Workaround

Microsoft provides two trace flags:

Trace Flag What It Does
11042 Forces queries using SESSION_CONTEXT to run serially — no parallelism
9432 Disables the CU14 fix that causes access violation dump files

TF 11042 is the one you want for most environments. It forces serial execution for any query that references SESSION_CONTEXT, which eliminates the parallel thread propagation problem entirely. The trade-off is performance — those queries lose parallelism. For many RLS and tenant-filter patterns, the queries are lightweight enough that serial execution will not matter.

TF 9432 disables the original fix, meaning you go back to pre-CU14 behavior: no access violations, but the wrong-results bug returns. Only use this if you are experiencing dump files and need to stop them immediately.

To enable globally:

-- Enable at runtime (survives until restart)
DBCC TRACEON(11042, -1);
GO

-- Verify
DBCC TRACESTATUS(11042, 9432);
GO

For persistence across restarts, add -T11042 to your SQL Server startup parameters.

Are You Exposed?

This query checks whether SESSION_CONTEXT appears in any cached plan that has executed with parallelism:

SELECT 
    qs.plan_handle,
    qs.sql_handle,
    qs.execution_count,
    qs.max_dop,
    SUBSTRING(st.text, 
        (qs.statement_start_offset / 2) + 1,
        ((CASE qs.statement_end_offset 
            WHEN -1 THEN DATALENGTH(st.text) 
            ELSE qs.statement_end_offset 
         END - qs.statement_start_offset) / 2) + 1) AS query_text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
WHERE st.text LIKE '%SESSION_CONTEXT%'
  AND qs.max_dop > 1
ORDER BY qs.execution_count DESC;

If that returns rows, you have queries using SESSION_CONTEXT that have executed with parallel plans. You have a problem.

Also check whether the trace flags are already enabled — if someone on your team found this before you did, you will want to know:

DBCC TRACESTATUS(11042, 9432);
GO

Bottom Line

SESSION_CONTEXT is Microsoft's recommended mechanism for passing application context into SQL Server. That recommendation has had a known parallel execution bug since January 2022. The original bug returns wrong results silently. A fix shipped in November 2021 (SQL Server 2019 CU14) stopped the wrong results but introduced access violation dump files. Neither problem has been fully resolved. The workaround is TF 11042, which forces affected queries to run serially.

Run the diagnostic query. If you get rows back, enable TF 11042. The performance cost of serial execution is almost always cheaper than the cost of returning inaccurate data.

More to Read:

Microsoft: SESSION_CONTEXT Known Issues
Microsoft: SQL Server 2025 CU2 (KB5075211)
Microsoft: KB5008114 — SESSION_CONTEXT Returns Wrong Results in Parallel Plans
Niko Neugebauer: SQL Server 2019 — Session Context & Parallel Plans

8 comments:

  1. Hi Rebecca, “buried” is overselling it a little. We have to put these things somewhere, and in this particular case it’s the order in which they were reported to the docs team. If you can help us to improve the Known issues article, you’re welcome to submit a pull request.

    ReplyDelete
    Replies
    1. Fair enough — 'buried' is my word, not yours, and I understand the docs team has a process. My readers aren't usually reading CU release notes proactively, though. They're reading them after something's already amiss — wrong results with no error, or a dump file they can't explain. By then, the ordering of the Known Issues list matters less than the fact that the workaround costs them parallelism on every query touching SESSION_CONTEXT. If I can help change the four years of 'Date resolved: (blank)', I'm in.

      Delete
    2. Yes, I'd love to see some collaboration to fix a multi-version bug that impacts us when we are following vendor guidance for context. Sounds like Rebecca is on to something.

      Delete
    3. Thanks! Three years across three versions is a long time for a known issue tied to vendor-recommended guidance. Hopefully it reaches the fix list soon.

      Delete
  2. Wow, my team planned to use this to replace `EXECUTE AS USER` for our multi-tenant. A problem like this, without returning any error for the client app, is so dangerous. Thanks for your article, very helpful.

    ReplyDelete
    Replies
    1. Glad it helped! Yeah, the silent failure is the worst part — at least a hard error gives you something to target. Definitely worth testing your use case thoroughly before going to prod. Let me know if I can help!

      Delete
  3. So using SESSION_CONTEXT in v2017, means that sometimes the value checked may not be found, or falsely sometimes the value checked may be found? We are about to introduce the use of SESSION_CONTEXT extensively in our v2017 (on prem, soon to be Azure) database. Maybe holding off until in Azure with DBCC TRACEON(11042, -1); would be best.

    ReplyDelete
  4. You don't have to wait for Azure. DBCC TRACEON(11042, -1) works on 2017 on-prem today. The bug is specific to parallel execution plans, so simple SESSION_CONTEXT reads may never trigger it. The trace flag trade-off is that it forces serial plans server-wide, so test before flipping it in production.

    ReplyDelete