The Symptom
Right after the upgrade, cloud applications using Microsoft Entra authentication can no longer connect. The SQL Server error log shows:
Login failed for user ''.
Reason: An attempt to login using SQL authentication failed.
Server is configured for Integrated authentication only.
That message sends most people straight to the authentication mode. Here, it was a dead end: SQL Server was configured for Mixed Mode, SQL logins worked, Windows logins worked, and Microsoft Entra authentication had been working fine on this exact instance before the upgrade. Nothing about the login configuration had changed. Something else broke.
What Was Already Correct
Before suspecting anything exotic, every standard Entra prerequisite got re-verified on the upgraded instance:
SELECT SERVERPROPERTY('IsIntegratedSecurityOnly')returned0: Mixed Mode was active.- The SQL Server service account, checked via
sys.dm_server_services, was unchanged. - The certificate in
Cert:\LocalMachine\Mywas present, not expired, and still had its private key. - The SQL Server service account still had Read permission on that private key (
certlm.msc→ Manage Private Keys). C:\Windows\System32\adal.dllexisted, andHKLM:\SOFTWARE\Microsoft\MSADALSQLstill pointed at it.- The cloud team confirmed the Entra app registration was intact: client ID, tenant ID, uploaded certificate, Microsoft Graph permissions, and admin consent all still in place.
Every documented prerequisite for Microsoft Entra authentication checked out. The failure was somewhere the standard checklist doesn't look.
The Actual Root Cause
Microsoft Entra authentication settings for a SQL Server instance live in the registry, under a path that is tied to the instance's internal version number:
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Microsoft SQL Server
MSSQL17.MSSQLSERVER
MSSQLServer
FederatedAuthentication
After the upgrade to SQL Server 2025, that key did not exist. MSSQL17 is the version-numbered instance ID for SQL Server 2025, distinct from MSSQL16 for SQL Server 2022. An in-place upgrade migrates the settings the setup engine treats as core instance state (authentication mode, service account, network configuration) into the new version's registry tree. FederatedAuthentication isn't one of them: it's written once, whenever Entra authentication is originally provisioned on the instance, and the upgrade routine simply never copies it forward to the new MSSQL17... path. Without that key, SQL Server has no configuration to initialize the Entra authentication provider, and it fails the login before ever getting to certificates or Microsoft Graph.
Rebuilding the Registry Key
The fix is to recreate the FederatedAuthentication key under the new version's instance path. Adjust the instance ID for a named instance (MSSQL17.<InstanceName> instead of MSSQL17.MSSQLSERVER), and substitute your certificate subject, client ID, and tenant ID:
$InstanceID = "MSSQL17.MSSQLSERVER"
$RegPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceID\MSSQLServer\FederatedAuthentication"
New-Item -Path $RegPath -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "AADCertSubjectName" -Value "CN=<Certificate Subject>" -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "AADTenantSpecificSQLServicePrincipalCertSubjectName" -Value "CN=<Certificate Subject>" -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "ClientId" -Value "<Application Client ID>" -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "AADTenantSpecificSQLServicePrincipalClientId" -Value "<Application Client ID>" -PropertyType String -Force | Out-Null
New-ItemProperty -Path $RegPath -Name "PrimaryAADTenant" -Value "<Tenant ID>" -PropertyType String -Force | Out-Null
The instance-specific values alone aren't enough; SQL Server also expects the standard set of default endpoints and limits under the same key:
$Values = @{
AADChannelMaxBufferedMessageSize = "200000"
AADGraphEndPoint = "graph.windows.net"
AADGroupLookupMaxRetryAttempts = "10"
AADGroupLookupMaxRetryDuration = "30000"
AADGroupLookupRetryInitialBackoff = "100"
AuthenticationEndpoint = "login.microsoftonline.com"
CacheMaxSize = "300"
FederationMetadataEndpoint = "login.windows.net"
GraphAPIEndpoint = "graph.windows.net"
IssuerURL = "https://sts.windows.net/"
MsGraphEndPoint = "graph.microsoft.com"
OnBehalfOfAuthority = "https://login.windows.net/"
SendX5c = "false"
ServicePrincipalName = "https://database.windows.net/"
ServicePrincipalNameForArcadia = "https://sql.azuresynapse.net"
ServicePrincipalNameForArcadiaDogfood = "https://sql.azuresynapse-dogfood.net"
ServicePrincipalNameNoSlash = "https://database.windows.net"
STSURL = "https://login.windows.net/"
ClientCertBlackList = ""
}
foreach ($Name in $Values.Keys) {
New-ItemProperty -Path $RegPath -Name $Name -Value $Values[$Name] -PropertyType String -Force | Out-Null
}
Verify and Restart
Confirm every value landed under the new instance path before restarting the service:
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL17.MSSQLSERVER\MSSQLServer\FederatedAuthentication" | Format-List *
Restart-Service MSSQLSERVER
Entra logins succeeded immediately after the restart, with no changes to the certificate, Microsoft Graph permissions, or the app registration. The registry key was the entire gap.
Best Practices
- ☐ Before any in-place major-version upgrade on an instance with Entra authentication enabled, export the existing
FederatedAuthenticationkey first:reg export "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQLServer\FederatedAuthentication" federatedauth-backup.reg. Rebuilding from a real export is safer and faster than retyping values by hand. - ☐ Add "check
FederatedAuthenticationunder the new instance ID" to the post-upgrade checklist for any instance using Entra authentication, right next to compatibility level and linked server checks. - ☐ Don't chase certificates, Microsoft Graph permissions, or the app registration on the strength of an "Integrated authentication only" error alone; confirm the registry key exists first, it takes thirty seconds and rules out the most common upgrade-specific cause.
- ☐ Match the instance ID to the actual product version (
MSSQL16= SQL Server 2022,MSSQL17= SQL Server 2025); a stale ID copied from an old script silently writes to the wrong tree. - ☐ For named instances, replace
MSSQLSERVERwith the real instance name in every path; the default-instance ID used throughout this article won't match. - ☐ Restart the SQL Server service after any change under this key; it's read at startup, not picked up live.
The Bottom Line
An in-place upgrade migrates what the setup engine considers core instance state; it doesn't migrate everything a feature needs to keep working. Microsoft Entra authentication's configuration lives entirely in a version-numbered registry path that the upgrade routine leaves behind, so the feature can go from working to broken without a single setting actually being wrong. The error message will point at authentication mode. The real gap is a registry key that never made the trip to the new instance ID.