The Problem
One morning users start complaining they cannot access OWA. Outlook shows “Trying to connect…” and never connects. You open the browser and see:
https://mail.company.com/owa/auth/errorFE.aspx?httpCode=500
Or worse: an ERR_TOO_MANY_REDIRECTS loop that never stops.
You RDP into the server. All Exchange services are running. IIS AppPools are started. Nothing looks obviously wrong.
This guide covers the exact scenario where Microsoft Exchange Server Auth Certificate expired and broke OWA Forms-Based Authentication (FBA) on Exchange 2016 CU22 and earlier.
Understanding What Broke
Exchange 2016 uses an internal Auth Certificate for two things:
- OAuth – server-to-server authentication between Exchange services
- HMAC cookie signing – OWA uses this certificate to sign and verify FBA session cookies
When this certificate expires, the HMACProvider component inside OWA cannot find a valid protection certificate. Every login attempt fails immediately after submitting credentials with HTTP 500.
The error you will find in Application Event Log:
[Owa] An internal server error occurred. The unhandled exception was: Microsoft.Exchange.Diagnostics.ExAssertException: ASSERT: HMACProvider.GetCertificates:protectionCertificates.Length<1 at Microsoft.Exchange.Clients.Common.HmacProvider.GetCertificates()
This is the root cause. Not IIS. Not AppPools. Not DNS. The certificate.
Step 1: Confirm the Root Cause
Open Exchange Management Shell (EMS) and run:
Get-ExchangeCertificate | fl Thumbprint, Subject, NotAfter, Services, Status
Look for this entry:
Subject : CN=Microsoft Exchange Server Auth Certificate NotAfter : [date in the past] Services : SMTP Status : Invalid
If NotAfter is in the past and Status is Invalid — that is your problem.
Also confirm what is currently assigned in AuthConfig:
Get-AuthConfig | fl CurrentCertificateThumbprint
Cross-reference that thumbprint with Get-ExchangeCertificate. If the assigned certificate is expired or missing: proceed with the fix below.
Step 2: Temporary Workaround (Keep Users Working)
While you fix the certificate, switch OWA to Windows Authentication so users can still access their mailboxes. Run this on each Exchange server:
Set-OwaVirtualDirectory "MAIL1\owa (Default Web Site)" -FormsAuthentication $false -WindowsAuthentication $true -BasicAuthentication $true Set-EcpVirtualDirectory "MAIL1\ecp (Default Web Site)" -FormsAuthentication $false -WindowsAuthentication $true -BasicAuthentication $true
iisreset /noforce
Users can now log in via Windows Authentication. Not ideal, but it keeps the business running while you fix the actual problem.
Step 3: Create a New Auth Certificate
Run this on MAIL1 (replace the DomainName values with your actual server FQDNs):
New-ExchangeCertificate -KeySize 2048 ` -PrivateKeyExportable $true ` -SubjectName "CN=Microsoft Exchange Server Auth Certificate" ` -FriendlyName "Microsoft Exchange Server Auth Certificate" ` -DomainName "mail1.company.com","mail2.company.com"
When asked “Overwrite the existing default SMTP certificate?” — answer N.
Copy the Thumbprint from the output. You will need it in the next step.
Step 4: Assign the New Certificate
$thumb = "PASTE_THUMBPRINT_HERE"
Set-AuthConfig -NewCertificateThumbprint $thumb -NewCertificateEffectiveDate (Get-Date)
Answer Y when warned about the 48-hour deployment window.
Set-AuthConfig -PublishCertificate
Set-AuthConfig -ClearPreviousCertificate
Verify the assignment:
Get-AuthConfig | fl CurrentCertificateThumbprint Get-ExchangeCertificate -Thumbprint $thumb | fl Subject, NotAfter, Status
You should see Status: Valid and NotAfter five years in the future.
Step 5: Fix IIS AppPool Permissions on the Certificate Key
This step is the one most guides skip – and it is often why OWA still fails after you replace the certificate.
Exchange AppPools run under virtual service accounts and need read access to the certificate’s private key file.
$thumb = (Get-AuthConfig).CurrentCertificateThumbprint $cert = Get-Item "Cert:\LocalMachine\MY\$thumb" $rsaKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert) $fileName = $rsaKey.Key.UniqueName $path = "$env:ALLUSERSPROFILE\Microsoft\Crypto\RSA\MachineKeys\$fileName" Write-Host "Key file: $path"
$acl = Get-Acl $path
foreach ($account in @(
"IIS AppPool\MSExchangeOWAAppPool",
"IIS AppPool\MSExchangeECPAppPool",
"IIS AppPool\MSExchangeRpcProxyFrontEndAppPool",
"IIS AppPool\MSExchangeServicesAppPool",
"NETWORK SERVICE",
"IIS_IUSRS"
)) {
try {
$rule = New-Object Security.AccessControl.FileSystemAccessRule($account, "FullControl", "Allow")
$acl.AddAccessRule($rule)
} catch { Write-Host "Skipped: $account" }
}
Set-Acl $path $acl
Write-Host "Done"
Step 6: Restart Services and Test
Restart-Service MSExchangeServiceHost -Force
iisreset /noforce
Open a browser and navigate to your OWA URL. If you still see HTTP 500, check the Event Log again – the HMACProvider error should now be gone and a different error (if any) will point you to the next issue.
Step 7: Repeat on Every Exchange Server in the DAG
The Auth Certificate must be created and the permissions must be set on each server individually. The certificate created on MAIL1 needs to exist on MAIL2 as well.
On MAIL2, run the same New-ExchangeCertificate command and then:
$thumb = (Get-AuthConfig).CurrentCertificateThumbprint
Check if the thumbprint matches what you set on MAIL1. If it does – just set the AppPool permissions (Step 5) on MAIL2.
If MAIL2 still shows the old expired certificate as current:
Set-AuthConfig -NewCertificateThumbprint "THUMBPRINT_FROM_MAIL1" -NewCertificateEffectiveDate (Get-Date) Set-AuthConfig -PublishCertificate Set-AuthConfig -ClearPreviousCertificate
Then repeat Step 5 and Step 6 on MAIL2.
Step 8: Re-enable Forms Authentication
Once OWA is working with Windows Auth confirmed, switch FBA back:
Set-OwaVirtualDirectory "MAIL1\owa (Default Web Site)" -FormsAuthentication $true -WindowsAuthentication $false -BasicAuthentication $false Set-EcpVirtualDirectory "MAIL1\ecp (Default Web Site)" -FormsAuthentication $true -WindowsAuthentication $false -BasicAuthentication $false
Set-OwaVirtualDirectory "MAIL2\owa (Default Web Site)" -FormsAuthentication $true -WindowsAuthentication $false -BasicAuthentication $false Set-EcpVirtualDirectory "MAIL2\ecp (Default Web Site)" -FormsAuthentication $true -WindowsAuthentication $false -BasicAuthentication $false
iisreset /noforce
Why CU22 Does Not Auto-Recover
Exchange 2016 CU22 (Build 2242.4) has a known defect where the HMACProvider does not automatically pick up a replacement Auth Certificate after the original expires. Replacing the certificate manually does not fully resolve the issue because the AppPool permission assignment is also broken in this build.
The permanent fix is upgrading to Exchange 2016 CU23 (Build 2507.x), which resolves the HMACProvider behavior and includes a self-healing mechanism for Auth Certificate rollover.
If you are on CU22 and cannot upgrade immediately, the workaround in this guide will keep OWA functional. Schedule the CU23 upgrade as soon as possible.
Quick Diagnostics Checklist
Use this when OWA is down and you need to identify the cause fast:
# 1. Check Auth Certificate status
Get-ExchangeCertificate | Where {$_.Subject -like "*Auth*"} | fl Thumbprint, NotAfter, Status
# 2. Check what is assigned in AuthConfig
Get-AuthConfig | fl CurrentCertificateThumbprint
# 3. Check the actual error in Event Log
Get-EventLog -LogName Application -Source *MSExchange* -EntryType Error -Newest 5 | fl TimeGenerated, Message
# 4. Check all Exchange services
Get-Service | Where {$_.Name -like "*Exchange*" -or $_.Name -eq "W3SVC"} | Where {$_.Status -eq "Stopped"} | ft Name, Status
# 5. Check IIS AppPools
Import-Module WebAdministration
Get-ChildItem IIS:\AppPools | Where {$_.Name -like "*Exchange*"} | ft Name, State
Prevention
Set a calendar reminder to check Exchange certificate expiry every 6 months:
Get-ExchangeCertificate | Sort NotAfter | ft Thumbprint, Subject, NotAfter, Services, Status
Any certificate expiring within 60 days should be renewed before it causes an outage.
For the Auth Certificate specifically, Microsoft recommends it be valid for at least 5 years. If you are creating it manually, always use -NotAfter (Get-Date).AddYears(5) or simply let the New-ExchangeCertificate command use its default 5-year validity.