Cumulative Update 8 for SQL Server 2025 landed on August 13th, build 17.0.4075.5. Eleven fixes. Three known issues. One of those known issues arrived with the July updates, and it is the kind that finds you at the worst possible moment, because the thing it breaks is the query you run when something is already going wrong.
Query sys.dm_exec_requests while a database is recovering and SQL Server may raise an access violation, write a stack dump, and terminate that session. Per KB5104822, this can happen during a RESTORE, during startup recovery, or before an availability group replica finishes coming online.
Here is the error log signature, as published by Microsoft in the KB:
The database '<DatabaseName>' is marked RESTORING and is in a state that does not allow recovery to be run.
***Stack Dump being sent to <SQLServerLogFolder>\SQLDump0215.txt
SqlDumpExceptionHandler: Process 77 generated fatal exception c0000005 EXCEPTION_ACCESS_VIOLATION. SQL Server is terminating this process.
*******************************************************************************
BEGIN STACK DUMP:
07/30/26 07:37:23 spid 77
Exception Code = c0000005 EXCEPTION_ACCESS_VIOLATION
Access Violation occurred reading address 00000000000000F0
Input Buffer <size> bytes -
<dbo.sp_YourMonitoringStoredProcedure>
Read that last line again. That is Microsoft's own placeholder in their own KB article. They named the input buffer sp_YourMonitoringStoredProcedure because they know exactly who is calling this DMV in a loop.
The Fix and the Bug Are the Same Code Change
This did not arrive out of nowhere. It arrived attached to something people asked for.
In the July CUs -- SQL Server 2025 CU7 and SQL Server 2022 CU26, both released July 16th -- Microsoft shipped a fix for monitoring queries that use sys.dm_exec_requests or sys.sysprocesses and intermittently fail against a secondary replica with error 976 or error 978. That is real annoying if you monitor a readable secondary, and it is a reasonable thing to fix.
KB5104822 describes the resulting problem plainly: "This issue occurs because of a change that causes internal in-memory structures to be referenced before they're fully initialized".
So the code change that stopped your monitoring query from erroring on a secondary is the same code change that can now crash it against a recovering database. You do not get to keep one and decline the other. Trace flag 4696 opts you out, and it opts you out of both.
Why This Lands Harder Than It Reads
A DMV that faults during database recovery sounds narrow. It is not, and here's why.
Look at the three windows Microsoft lists -- a RESTORE, startup recovery, and an AG replica coming online. Every one of those is a window where a DBA or a monitoring platform is actively watching. Nobody polls sys.dm_exec_requests harder than during a restore that is taking longer than expected, or a service restart, or a failover. The exposure is not spread evenly across your week. It is concentrated in exactly the minutes you are paying attention.
Then there is the part that made me sit up. Your patching window manufactures the condition. The restart the install requires puts the instance into startup recovery on the new build, and on an AG the replicas come online one at a time. A scheduled monitoring sweep that fires in that window is your first exposure, minutes after you introduced it.
Worth being clear on what this does and does not take down. Per KB5104822, the AV terminates the process, not the instance -- "SQL Server is terminating this process". Your instance is not going down. But a stack dump is not free. Dump generation costs I/O and time on a server that is, by definition, already busy recovering something.
Who Is Exposed
| Version | Build | Released | Status |
|---|---|---|---|
| SQL Server 2025 CU8 | 17.0.4075.5 | Aug 13, 2026 | Known issue, open |
| SQL Server 2025 CU7 | 17.0.4065.4 | Jul 16, 2026 | Known issue, open |
| SQL Server 2022 CU26 | 16.0.4265.3 | Jul 16, 2026 | Known issue, open |
Microsoft's position as of CU8 is that they are aware of the issue and investigating a fix. No fix build to point at yet, and CU8 shipping without one tells you it did not make the August train.
Find Out Where You Stand
Three questions, three answers. Start with the build, because everything else depends on it.
1. What am I actually running?
SELECT
SERVERPROPERTY('ProductVersion') AS Build,
SERVERPROPERTY('ProductUpdateLevel') AS CU,
SERVERPROPERTY('ProductLevel') AS ProductLevel,
SERVERPROPERTY('Edition') AS Edition;
GO
If Build comes back 17.0.4065.4 like mine, or 17.0.4075.5, or 16.0.4265.3, you are on an affected build.
2. Is anything in a recovering state right now?
SELECT
d.name,
d.state_desc,
d.recovery_model_desc
FROM sys.databases d
WHERE d.state_desc <> 'ONLINE'
ORDER BY d.name;
GO
Empty result set is what you want. This is also the check worth running before you start a monitoring sweep, which I come back to below.
3. Is trace flag 4696 already on?
DBCC TRACESTATUS(4696, -1); GO
Your Three Options
KB5104822 gives exactly three mitigations, and there is no free one in the set. Pick your poison deliberately.
| Mitigation | What you get | What it costs |
|---|---|---|
| Trace flag 4696 | Opts out of the code change. No AV. | Monitoring queries against sys.dm_exec_requests or sys.sysprocesses on secondary replicas can return errors 976 or 978 again, exactly as before July. |
| Avoid the DMV during recovery | Keeps the July fix. No trace flag. | Requires you to change your monitoring code, and it is a timing problem, not a settings problem. |
| Uninstall the update | Back to a known state. | You also give up every security fix in the July and August packages. For most shops this is not a real option. |
My read: trace flag 4696 is the sane default for anyone whose estate has availability groups, log shipping, or regular restores -- which is most of us. A monitoring query that returns an error is a nuisance you can see and log. A session that gets terminated mid-sweep during a failover is a nuisance you find out about later, from the dump directory.
-- Global, effective immediately DBCC TRACEON (4696, -1); -- Or make it survive a restart, as a startup parameter: -- -T4696
Test it before production. You are trading one documented behavior for another documented behavior, and which one hurts you less depends on whether your secondaries are readable.
A Guard For Your Monitoring Job
If you would rather keep the July fix and skip the trace flag, the shape of the mitigation is to not run the DMV query while anything is recovering. Something like this:
/* UNVERIFIED -- pattern only. I have not reproduced the AV,
and this has not been tested against an affected build. */
IF EXISTS
(
SELECT 1
FROM sys.databases
WHERE state_desc IN ('RECOVERING', 'RECOVERY_PENDING', 'RESTORING')
)
BEGIN
/* Skip the sweep this cycle and say so, loudly */
RAISERROR ('Monitoring sweep skipped -- database(s) in a recovering state.', 10, 1) WITH LOG;
END
ELSE
BEGIN
SELECT
r.session_id,
r.status,
r.command,
r.wait_type,
r.wait_time,
r.blocking_session_id
FROM sys.dm_exec_requests r
WHERE r.session_id > 50;
END;
GO
Be honest with yourself about what that buys you. It is a check-then-act, and the state can change between the check and the query. It narrows the window, but it doesn't close it. And it means your monitoring goes quiet during precisely the events you most want monitored, which is its own kind of failure. I am showing it because it is the shape of Microsoft's second mitigation, not because I think it is a good outcome.
And While You Are In There
CU8 carries two other known issues and one of them is an old friend.
SESSION_CONTEXT in parallel plans. Still there. Same text as it has carried for years -- incorrect results or AV dump files in parallel query plans, because of how SESSION_CONTEXT interacts with parallel execution threads when the session is reset for reuse. I wrote about it in March, and again when CU6 shipped without fixing it. Trace flag 11042 remains the workaround. That is coming up on five years.
Bottom Line
None of this is an argument against patching. The July packages carried security content and you need it. It is an argument for reading the Known Issues section before you schedule the window, and for a specific ordering on your patch nights.
If you patch an availability group this month, the replicas coming back online are the exact condition described in the KB. Decide what your monitoring is doing during that window before you start, not after you find the dump files. Set the trace flag, or pause the sweep -- or at the very minimum, just know the risk is there and go look at the log afterward.
The uncomfortable part of this one is not that a DMV can fault. It is that the fault arrived as a fix, shipped in a package everybody had a good reason to install, and lands on the tool you reach for when something is already broken.
More to Read
MSFT -- KB5104822, Cumulative Update 8 for SQL Server 2025
MSFT -- KB5096981, Cumulative Update 7 for SQL Server 2025
MSFT -- KB5093420, Cumulative Update 26 for SQL Server 2022
MSFT Tech Community -- Cumulative Update 8 for SQL Server 2025 RTM
MSFT -- SESSION_CONTEXT, Known Issues
sqlfingers -- CU6 Is Here. SESSION_CONTEXT Is Still Broken in Parallel
sqlfingers -- SESSION_CONTEXT: Three Years, Two Bugs, One Workaround
No comments:
Post a Comment