Why This Error Happens
Error 3949 occurs when a readable secondary replica in an Always On Availability Group attempts to access a versioned row (used for row versioning under RCSI or Snapshot Isolation) that was never properly created because the operation generating that version was executed directly on the secondary rather than the primary. This typically happens due to replication latency, aggressive version store cleanup, or when long-running read queries on the secondary outlast the retention window of the version store. It can also surface when the secondary’s redo thread is significantly behind the primary, causing version mismatches during row retrieval.
Step-by-Step Resolution Guide
Step 1: Check Availability Group Replication Latency
- Open SQL Server Management Studio (SSMS) and connect to the primary replica.
- Run
SELECT * FROM sys.dm_hadr_database_replica_states;to checkredo_queue_sizeandlog_send_queue_size. - If the secondary is significantly behind, investigate network throughput or disk I/O bottlenecks on the secondary node using Windows Performance Monitor (
perfmon.exe).
Step 2: Increase Version Store Retention on the Primary
- Navigate to the primary replica and verify the
REQUIRED_SECONDARY_REPLICAS_TO_COMMITsetting is not causing unintended delays. - Run the following to check current retention behavior:
SELECT name, is_read_committed_snapshot_on, snapshot_isolation_state_desc
FROM sys.databases WHERE name = 'YourDatabaseName';
- Consider enabling
ALTER DATABASE SCOPED CONFIGURATION SET ACCELERATED_DATABASE_RECOVERY = ON;if not already active, as ADR helps manage version store cleanup more efficiently in SQL Server 2025.
Step 3: Adjust Query Timeout and Retry Logic on Secondary
- On the secondary replica, identify long-running read queries using:
SELECT * FROM sys.dm_exec_requests WHERE command = 'SELECT';
- Reduce query duration by adding appropriate indexing or breaking large read operations into smaller batches.
- Implement application-side retry logic for Error 3949, since it is often transient and resolves on re-execution once version data synchronizes.
Step 4: Validate Read-Only Routing Configuration
- Open a PowerShell session as Administrator and verify the Availability Group listener configuration:
Get-ClusterGroup | Where-Object {$_.GroupType -eq "AvailabilityGroup"}
- Confirm
ALLOW_CONNECTIONS = READ_ONLYis correctly set on the intended secondary replicas in SSMS under Always On High Availability > Availability Group Listeners. - Restart the SQL Server service on the secondary node via
services.mscif configuration changes were made.
Alternative or Verification Steps
- To verify the fix, run your original read-only workload against the secondary replica during a period of active writes on the primary and confirm no 3949 errors appear in the SQL Server Error Log (
Management > SQL Server Logsin SSMS). - If the issue persists, consider failing over the Availability Group temporarily and rebuilding the secondary replica from a fresh backup to eliminate any underlying version store corruption.