|
| 1 | +--- |
| 2 | +title: "MSSQLSERVER_988" |
| 3 | +description: "MSSQLSERVER_988" |
| 4 | +author: prmadhes-msft |
| 5 | +ms.author: prmadhes |
| 6 | +ms.reviewer: randolphwest |
| 7 | +ms.date: 07/17/2025 |
| 8 | +ms.service: sql |
| 9 | +ms.subservice: supportability |
| 10 | +ms.topic: "reference" |
| 11 | +helpviewer_keywords: |
| 12 | + - "988 (Database Engine error)" |
| 13 | +--- |
| 14 | +# MSSQLSERVER_988 |
| 15 | + |
| 16 | +[!INCLUDE [SQL Server](../../includes/applies-to-version/sqlserver.md)] |
| 17 | + |
| 18 | +## Details |
| 19 | + |
| 20 | +| Attribute | Value | |
| 21 | +| --- | --- | |
| 22 | +| Product Name | SQL Server | |
| 23 | +| Event ID | 988 | |
| 24 | +| Event Source | MSSQLSERVER | |
| 25 | +| Component | SQLEngine | |
| 26 | +| Symbolic Name | DB_HADRON_DATABASE_NO_QUORUM | |
| 27 | +| Message Text | Unable to access database '%.\*ls' because it lacks a quorum of nodes for high availability. Try the operation again later. | |
| 28 | + |
| 29 | +## Symptoms |
| 30 | + |
| 31 | +When you attempt to add a database to an Always On availability group or perform read/write operations on the primary replica, you might receive the following SQL Server error 988: |
| 32 | + |
| 33 | +```output |
| 34 | +Unable to access database '<DB Name>' because it lacks a quorum of nodes for high availability. (Microsoft SQL Server, Error: 988) |
| 35 | +``` |
| 36 | + |
| 37 | +This error indicates that the database can't be accessed or added because the required number of synchronized secondary replicas isn't available to commit the transaction. |
| 38 | + |
| 39 | +## Cause |
| 40 | + |
| 41 | +The [REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT](../../t-sql/statements/alter-availability-group-transact-sql.md#required_synchronized_secondaries_to_commit) setting enforces that the primary replica must wait for a specified number of synchronous secondary replicas to harden each transaction before committing. If the required number of replicas isn't online, connected, and synchronized, you might encounter the following issues, which lead to blocking or failure scenarios that trigger error 988. |
| 42 | + |
| 43 | +- The primary replica can't complete commits. |
| 44 | +- A database being added can't complete the join process, as secondaries aren't yet participating. |
| 45 | + |
| 46 | +## Scenarios |
| 47 | + |
| 48 | +You might encounter this error in the following scenarios: |
| 49 | + |
| 50 | +### Scenario 1: Add a new database |
| 51 | + |
| 52 | +When a new database is added to the availability group, secondaries aren't yet part of the group and can't acknowledge the commit, causing a blocking condition. |
| 53 | + |
| 54 | +### Scenario 2: Runtime commit failures |
| 55 | + |
| 56 | +When the configured value of `REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT` is greater than the number of available healthy synchronous secondaries, the primary can't proceed with commits. |
| 57 | + |
| 58 | +## Workaround |
| 59 | + |
| 60 | +To work around this issue, use one of the following options: |
| 61 | + |
| 62 | +### Option 1: Adjust the REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT setting |
| 63 | + |
| 64 | +Lowering the value to `0` allows the primary to commit without waiting for synchronous secondaries. |
| 65 | + |
| 66 | +> [!WARNING] |
| 67 | +> This option improves availability but increases the risk of data loss in failover scenarios. |
| 68 | +
|
| 69 | +#### Use SQL Server Management Studio (SSMS) |
| 70 | + |
| 71 | +1. Navigate to the availability group name in SSMS. |
| 72 | +1. Right-click the name and select **Properties**. |
| 73 | +1. Set the **REQUIRED SYNCHRONIZED SECONDARIES TO COMMIT** value to `0` or an appropriate value. |
| 74 | + |
| 75 | +#### Use T-SQL |
| 76 | + |
| 77 | +Run the following query: |
| 78 | + |
| 79 | +```sql |
| 80 | +ALTER AVAILABILITY GROUP [AGNAME] SET (REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0); |
| 81 | +``` |
| 82 | + |
| 83 | +### Option 2: Pre-Seed the Secondary Replicas (for Adding Databases) |
| 84 | + |
| 85 | +Make sure that secondaries are ready before adding a database. Then, use automatic seeding, or manually restore the database on each secondary by using the **Join only** option. |
| 86 | + |
| 87 | +## Troubleshooting |
| 88 | + |
| 89 | +To diagnose and resolve this issue, follow these steps: |
| 90 | + |
| 91 | +### Step 1: Confirm the REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT setting |
| 92 | + |
| 93 | +To verify if the `REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT` setting is enabled for your availability group (AG), use SSMS, or T-SQL. If the value is `1` or higher, proceed to [Step 2: Verify the state of synchronous secondary replicas](#step-2-verify-the-state-of-synchronous-secondary-replicas). |
| 94 | + |
| 95 | +#### Use SSMS |
| 96 | + |
| 97 | +1. Navigate to the availability group name in SSMS. |
| 98 | +1. Right-click the name and select **Properties**. |
| 99 | +1. Check the **REQUIRED SYNCHRONIZED SECONDARIES TO COMMIT** value. |
| 100 | + |
| 101 | +#### Use T-SQL |
| 102 | + |
| 103 | +Run the following query on the primary replica: |
| 104 | + |
| 105 | +```sql |
| 106 | +SELECT name AS Availability_group_name, |
| 107 | + required_synchronized_secondaries_to_commit, |
| 108 | + * |
| 109 | +FROM sys.availability_groups; |
| 110 | +``` |
| 111 | + |
| 112 | +> [!NOTE] |
| 113 | +> This query can be executed even if the 988 error starts occurring. |
| 114 | +
|
| 115 | +### Step 2: Verify the state of synchronous secondary replicas |
| 116 | + |
| 117 | +To check if the minimum number of synchronous secondary replicas are connected, synchronized, and healthy, use SSMS, or T-SQL. |
| 118 | + |
| 119 | +#### Use SSMS |
| 120 | + |
| 121 | +1. Open **Availability Groups Dashboard** on the primary replica. |
| 122 | +1. Review the state of secondary replicas. |
| 123 | + |
| 124 | +#### Use T-SQL |
| 125 | + |
| 126 | +Run the following query: |
| 127 | + |
| 128 | +```sql |
| 129 | +SELECT ag.name AS Availability_group_name, |
| 130 | + drcs.database_name, |
| 131 | + ar.replica_server_name, |
| 132 | + ars.role_desc, |
| 133 | + ars.connected_state_desc, |
| 134 | + ars.synchronization_health_desc, |
| 135 | + ars.last_connect_error_description, |
| 136 | + ars.last_connect_error_number, |
| 137 | + ars.last_connect_error_timestamp, |
| 138 | + ar.endpoint_url |
| 139 | +FROM sys.dm_hadr_availability_replica_states AS ars |
| 140 | + INNER JOIN sys.availability_replicas AS ar |
| 141 | + ON ars.replica_id = ar.replica_id |
| 142 | + INNER JOIN sys.availability_groups AS ag |
| 143 | + ON ar.group_id = ag.group_id |
| 144 | + INNER JOIN sys.dm_hadr_database_replica_cluster_states AS drcs |
| 145 | + ON ar.replica_id = drcs.replica_id; |
| 146 | +``` |
| 147 | + |
| 148 | +Make sure that the number of `CONNECTED`, `SYNCHRONIZED`, and `HEALTHY` replicas matches the `REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT` setting. |
| 149 | + |
| 150 | +The following extended event session captures commit policy settings and synchronization state changes to diagnose why required synchronized secondaries prevent transaction commits in SQL Server Always On availability groups. |
| 151 | + |
| 152 | +```sql |
| 153 | +CREATE EVENT SESSION [ag_state_change] ON SERVER |
| 154 | +ADD EVENT sqlserver.alwayson_ddl_executed |
| 155 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)), |
| 156 | +ADD EVENT sqlserver.hadr_db_commit_mgr_harden |
| 157 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)), |
| 158 | +ADD EVENT sqlserver.hadr_db_commit_mgr_set_policy |
| 159 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)), |
| 160 | +ADD EVENT sqlserver.hadr_db_commit_mgr_update_harden |
| 161 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)), |
| 162 | +ADD EVENT sqlserver.hadr_db_partner_set_policy |
| 163 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)), |
| 164 | +ADD EVENT sqlserver.hadr_db_partner_set_sync_state |
| 165 | + (ACTION (sqlos.system_thread_id, sqlserver.session_id, sqlserver.sql_text)) |
| 166 | +ADD TARGET package0.event_file |
| 167 | + (SET filename = N'ag_state_change') |
| 168 | +WITH |
| 169 | +( |
| 170 | + MAX_MEMORY = 4096 KB, |
| 171 | + EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, |
| 172 | + MAX_DISPATCH_LATENCY = 30 SECONDS, |
| 173 | + MAX_EVENT_SIZE = 0 KB, |
| 174 | + MEMORY_PARTITION_MODE = NONE, |
| 175 | + TRACK_CAUSALITY = OFF, |
| 176 | + STARTUP_STATE = OFF |
| 177 | +); |
| 178 | +GO |
| 179 | +``` |
| 180 | + |
| 181 | +The **hadr_db_commit_mgr_update_harden** event could be used to identify the issue. When the issue occurs, the **MinSyncCommitFailure** status means there aren't enough synchronization secondaries to meet the configured minimum synchronization count. |
0 commit comments