Introduction to Windows Server Failover Clustering with SQL Server
Windows Server Failover Clustering (WSFC) combined with SQL Server Failover Cluster Instances (FCI) is one of the oldest and most battle-tested high-availability solutions for SQL Server workloads. Unlike Always On Availability Groups, which replicate data between nodes, a Failover Cluster Instance presents SQL Server as a single named instance that lives on shared storage — any node in the cluster can own the SQL Server resources at any given time, and clients always connect to the same virtual network name regardless of which physical node is active.
This guide walks through the complete setup of a two-node WSFC on Windows Server 2022, followed by installing SQL Server 2022 as a Failover Cluster Instance. The process involves Active Directory preparation, shared storage configuration, cluster validation and creation, and then the SQL Server FCI installation itself.
Prerequisites and Environment Requirements
Before you begin, ensure the following conditions are met across all nodes. Both servers must be domain-joined — WSFC requires Active Directory for cluster name objects (CNOs) and virtual computer objects (VCOs). The account used to create the cluster must have permission to create computer objects in the target AD organizational unit, or you must pre-stage the CNO manually.
Shared storage is mandatory for SQL Server FCI. Each node must have identical access to the same LUNs. Common options include iSCSI (via Windows iSCSI Initiator), Fibre Channel HBAs connected to a SAN, or SMB 3.x file shares (SQL Server 2012+ supports SMB for data files). For iSCSI, configure the iSCSI Initiator on each node:
iscsicpl.exe
Or via PowerShell, connect to an iSCSI target portal:
New-IscsiTargetPortal -TargetPortalAddress 192.168.10.50
Get-IscsiTarget | Connect-IscsiTarget -IsPersistent $true
Once shared disks are visible on both nodes, initialize and format them on the first node only. Do not bring them online simultaneously on both nodes before the cluster is formed — this will corrupt the disk.
Network requirements: each node should have at minimum two NICs — one for client traffic and one dedicated cluster heartbeat network. Assign static IPs to all NICs. The cluster will need an additional IP address for the cluster name itself, and SQL Server FCI will require yet another IP address and virtual network name.
Installing the Failover Clustering Feature
Install the Failover Clustering feature on all nodes. Run the following on each server:
Install-WindowsFeature -Name Failover-Clustering -IncludeManagementTools
Install-WindowsFeature -Name RSAT-Clustering-PowerShell
After installation, run the cluster validation wizard. This is mandatory — Microsoft only supports clusters that pass validation. Run from any node:
Test-Cluster -Node "NODE1", "NODE2" -Include "Storage", "Network", "System Configuration", "Hyper-V Configuration"
Review the HTML report generated by the validation. Warnings on certain Hyper-V checks can be ignored for physical server deployments. Storage tests will verify that both nodes can see the shared disks and that only one can be online at a time. Fix any errors before proceeding — particularly around storage bus resets and network redundancy.
Creating the Windows Server Failover Cluster
Once validation passes, create the cluster. Choose a cluster name (CNO) and a dedicated cluster IP address:
New-Cluster -Name "SQLCLUSTER01" -Node "NODE1","NODE2" -StaticAddress 192.168.1.50 -NoStorage
The -NoStorage flag prevents automatic assignment of all shared disks to the cluster storage pool — this gives you manual control. After the cluster is created, add the shared disks manually:
Get-ClusterAvailableDisk | Add-ClusterDisk
Designate one disk as the quorum witness (for a two-node cluster, use a File Share Witness or a Cloud Witness instead of a disk quorum to avoid a single point of failure):
# Configure a Cloud Witness (Azure storage account)
Set-ClusterQuorum -CloudWitness -AccountName "mystorageaccount" -AccessKey "base64key=="
# Or configure a File Share Witness
Set-ClusterQuorum -FileShareWitness "\fileserversqlclusterwitness"
Verify cluster health:
Get-Cluster | Select-Object Name, QuorumType, SharedVolumesRoot
Get-ClusterNode | Select-Object Name, State, NodeWeight
Get-ClusterResource | Select-Object Name, ResourceType, State, OwnerNode
Installing SQL Server 2022 as a Failover Cluster Instance
SQL Server FCI setup must be run with elevated privileges from the node that currently owns the cluster storage. The installation is a two-phase process: first install the FCI on the primary node, then add the second node. Mount the SQL Server 2022 ISO or extract it, then launch the command-line setup:
setup.exe /Action=InstallFailoverCluster ^
/FEATURES=SQLENGINE,REPLICATION,FULLTEXT ^
/INSTANCENAME="MSSQLSERVER" ^
/SQLSVCACCOUNT="DOMAINsvc-sql" ^
/SQLSVCPASSWORD="P@ssword123" ^
/AGTSVCACCOUNT="DOMAINsvc-sqlagent" ^
/AGTSVCPASSWORD="P@ssword123" ^
/INSTALLSQLDATADIR="G:" ^
/SQLUSERDBDIR="G:SQLData" ^
/SQLUSERDBLOGDIR="G:SQLLog" ^
/SQLTEMPDBDIR="G:TempDB" ^
/INSTALLSHAREDDIR="C:Program FilesMicrosoft SQL Server" ^
/FAILOVERCLUSTERNETWORKNAME="SQLFCI01" ^
/FAILOVERCLUSTERIPADDRESSES="IPv4;192.168.1.55;Cluster Network 1;255.255.255.0" ^
/FAILOVERCLUSTERDISKS="Cluster Disk 1" ^
/SAPWD="AdminPass123!" ^
/SECURITYMODE=SQL ^
/SQLSYSADMINACCOUNTS="DOMAINSQLAdmins" ^
/IACCEPTSQLSERVERLICENSETERMS ^
/QUIET
The /FAILOVERCLUSTERNETWORKNAME parameter sets the virtual network name clients use to connect. The /FAILOVERCLUSTERIPADDRESSES parameter defines the virtual IP. The /FAILOVERCLUSTERDISKS must match the exact cluster disk name as shown in Failover Cluster Manager.
After the primary node installation completes, add the second node:
setup.exe /Action=AddNode ^
/INSTANCENAME="MSSQLSERVER" ^
/CONFIRMIPDEPENDENCYCHANGE=0 ^
/SQLSVCACCOUNT="DOMAINsvc-sql" ^
/SQLSVCPASSWORD="P@ssword123" ^
/AGTSVCACCOUNT="DOMAINsvc-sqlagent" ^
/AGTSVCPASSWORD="P@ssword123" ^
/FAILOVERCLUSTERNETWORKNAME="SQLFCI01" ^
/IACCEPTSQLSERVERLICENSETERMS ^
/QUIET
SQL Server Cluster Resource Dependencies
After installation, open Failover Cluster Manager and examine the SQL Server role. The resource dependency chain is critical. The SQL Server service resource must depend on the SQL Server Network Name, which in turn depends on the virtual IP address, which depends on the cluster network. The shared disk resource must also be a dependency of the SQL Server service.
View and modify dependencies using PowerShell:
# View current dependencies for the SQL Server resource
Get-ClusterResourceDependency -Resource "SQL Server (MSSQLSERVER)"
# Add a dependency
Add-ClusterResourceDependency -Resource "SQL Server (MSSQLSERVER)" -Provider "Cluster Disk 2"
# View the full dependency expression
(Get-ClusterResource "SQL Server (MSSQLSERVER)").DependencyExpression
If SQL Server stores TempDB on a local SSD for performance (supported since SQL Server 2019), that disk should NOT be a cluster dependency — it should be formatted and available locally on each node.
Testing SQL Server FCI Failover
To test failover, move the SQL Server cluster role to the other node. First confirm the current owner:
Get-ClusterGroup -Name "SQL Server (MSSQLSERVER)" | Select-Object Name, OwnerNode, State
Initiate a graceful failover:
Move-ClusterGroup -Name "SQL Server (MSSQLSERVER)" -Node "NODE2"
Monitor the move:
Get-ClusterGroup -Name "SQL Server (MSSQLSERVER)" | Select-Object Name, OwnerNode, State
Get-ClusterEvent | Select-Object -First 20
Typical failover time for SQL Server FCI is 20–90 seconds depending on database recovery. Client connections using the virtual network name will reconnect automatically after the SQL Server service starts on the new node. Test client connectivity by running:
sqlcmd -S SQLFCI01 -Q "SELECT @@SERVERNAME, @@VERSION, SERVERPROPERTY('ComputerNamePhysicalNetBIOS')"
The ComputerNamePhysicalNetBIOS will show the new physical node name, confirming failover completed.
SQL Server FCI vs Always On Availability Groups
Understanding when to choose FCI over AG (Availability Groups) is important for architects. FCI provides instance-level HA — the entire SQL Server instance, including all databases, agent jobs, linked servers, and logins, fails over as a unit. AG replicates specific databases between independent SQL Server instances, giving per-database granularity and enabling readable secondaries.
FCI requires shared storage, making it more expensive in hardware or cloud environments. AG uses log shipping internally and works with local storage on each node, making it cloud-friendly and well-suited for Azure VMs. FCI failover affects all databases simultaneously; AG allows individual databases to be moved independently. In practice, many organizations combine both: an FCI for local HA within a datacenter, and an AG for disaster recovery to a remote site. This is called a Distributed Availability Group or an FCI+AG topology.
For licensing, FCI requires SQL Server licenses on all passive nodes in certain scenarios — check current Microsoft licensing documentation as rules have changed across SQL Server versions.
Maintenance Mode and Patching SQL Server FCI Nodes
When patching SQL Server or the OS on cluster nodes, use the rolling upgrade procedure. Start with the passive node. Suspend the node from cluster participation (for OS patching):
# Pause the node (removes it from hosting workloads)
Suspend-ClusterNode -Name "NODE2" -Drain
# Verify node is paused
Get-ClusterNode "NODE2" | Select-Object Name, State
Apply Windows Updates or SQL Server Cumulative Updates on NODE2. For SQL Server patching, run the CU setup on the passive node:
SQLServer2022-KB5040939-x64.exe /Action=Patch /InstanceName=MSSQLSERVER /IAcceptSQLServerLicenseTerms /Quiet
After patching NODE2, resume it and then fail over SQL Server to NODE2:
Resume-ClusterNode -Name "NODE2"
Move-ClusterGroup -Name "SQL Server (MSSQLSERVER)" -Node "NODE2"
Now NODE1 is passive. Apply the same patches to NODE1, then optionally fail back. This rolling patch approach ensures zero downtime for patching when done during low-traffic windows.
For OS-level updates requiring a reboot, use Cluster-Aware Updating (CAU) which automates this process and handles the drain, reboot, and resume sequence automatically across all nodes in the cluster.
Monitoring and Troubleshooting WSFC with SQL Server
The cluster log is the primary diagnostic tool. Generate it for all nodes:
Get-ClusterLog -Destination "C:ClusterLogs" -TimeSpan 60 -UseLocalTime
The Windows System Event Log and the Application Event Log on each node will contain SQL Server and cluster events. Filter for critical cluster events:
Get-WinEvent -LogName System -FilterXPath "*[System[Provider[@Name='Microsoft-Windows-FailoverClustering']]]" | Select-Object -First 30 TimeCreated, Id, Message
SQL Server writes FCI failover events to the SQL Server error log. Check the current and archived error logs:
sqlcmd -S SQLFCI01 -Q "EXEC xp_readerrorlog 0, 1, N'failover', NULL, NULL, NULL, N'asc'"
Common issues include quorum loss (usually due to witness unavailability), disk arbitration failures (check iSCSI or FC connectivity from both nodes), and network partition (ensure the heartbeat network is healthy and firewalls allow UDP 3343 for cluster communication). With proper planning and monitoring, WSFC+SQL Server FCI delivers reliable HA for critical database workloads on Windows Server 2022.