Fix it now
0x80090331 is Windows reporting that your server and the far end do not possess a common algorithm, so the handshake had nothing to agree on. Against Microsoft 365 that almost always means your side is offering protocol versions and cipher suites the service no longer accepts. Registry work fixes a server that merely has TLS 1.2 switched off; it cannot add capability a build does not have.
Get-ExchangeServer | Format-List Name,Edition,AdminDisplayVersion
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -Force | Out-Null
New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Force | Out-Null
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -Name "DisabledByDefault" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Name "DisabledByDefault" -Value 0 -Type DWord
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" -Name "Enabled" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SystemDefaultTlsVersions" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SystemDefaultTlsVersions" -Value 1 -Type DWord
Set-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value 1 -Type DWord
- Read the Schannel entries in Windows Logs then System first. Event 36888 means your server generated the alert; 36887 means it received one. The two point at opposite ends.
- Both .NET paths matter.
SchUseStrongCryptoaffects only outgoing connections, andSystemDefaultTlsVersionsis what lets managed components inherit the operating system’s choice instead of the framework’s. - Reboot. Microsoft is explicit that the Exchange TLS configuration becomes active only after the server restarts.
- If the build is past end of support and the values are already correct, stop configuring. Exchange Server 2016 and 2019 reached end of support on 14 October 2025, and no registry value adds a cipher suite the code does not implement.
These values change how the whole server negotiates encryption, not just Exchange. Export each key first, change one thing at a time, and have console access available before you start.
If the handshake completes after the reboot, you are done. If it still fails, the next section explains how to tell a configuration problem from a capability problem.
Why it happens
A TLS handshake starts with one side offering a list: the protocol versions and cipher suites it is willing to use. The other picks one it also supports and the session proceeds. If the intersection is empty there is nothing to pick and the handshake ends. Windows publishes 0x80090331 as SEC_E_ALGORITHM_MISMATCH, meaning the client and server cannot communicate because they do not possess a common algorithm. It says nothing about certificates or names.
Two Schannel events describe the same handshake from opposite ends, and the direction is the most useful thing you can establish. Event 36888 is logged when this computer detects an error condition and generates a fatal alert to notify the other party: your side rejected what they offered. Event 36887 is logged when this computer receives a fatal alert from the far end: they rejected what you offered. Event 36874 is more specific still, reporting that a connection request arrived and none of the cipher suites the client supports are supported by the server.
If Microsoft 365 sends you the alert, nothing on their side will change. Microsoft has steadily retired older TLS versions and weaker suites across its services, so a server that was fine for years fails without anything on your network changing. That is the moment to establish which problem you have. TLS 1.2 support was introduced with Exchange Server 2013 CU19 and Exchange Server 2016 CU8, and Exchange Server 2019 supports it by default, so anything older than those cumulative updates is a capability problem rather than a configuration one.
TLS 1.2 is supported by the build but switched off
You have this one if A build that supports TLS 1.2, and the Schannel protocol keys either missing or explicitly disabling it.
- Export the Schannel protocols key before making any change.
- Create the
TLS 1.2key and itsClientandServersubkeys if they are absent, then setEnabledto 1 andDisabledByDefaultto 0 as DWORDs under both. - Leave older protocol versions alone until the new one is proven, then retire them deliberately.
- Reboot and retest. A partial application of these values produces confusing intermittent results.
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client
HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server
Enabled REG_DWORD 1
DisabledByDefault REG_DWORD 0
Both subkeys are needed. A server that accepts TLS 1.2 inbound but will not use it outbound still fails whenever it is the one initiating the connection, which is every message it sends.
The .NET runtime is negotiating with its own defaults
You have this one if The operating system offers TLS 1.2 correctly, but managed components and hybrid connectivity still fail.
- Export the .NET framework keys before editing.
- Set
SystemDefaultTlsVersionsandSchUseStrongCryptoto 1 in both the 64-bit path and the Wow6432Node path. - Set them for the framework version in use:
v4.0.30319for .NET Framework 4 and above,v2.0.50727for 3.5. - Reboot the server, then retest the specific component that was failing rather than assuming the whole server is fixed.
HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319
HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319
SystemDefaultTlsVersions REG_DWORD 1
SchUseStrongCrypto REG_DWORD 1
A hardening baseline disabled the suites both sides needed
You have this one if Your server generates the fatal alert, and a security baseline or third-party hardening tool was applied recently.
- Review what the baseline disabled, including cipher suite ordering rather than only protocol versions.
- Re-enable the suites required by the partners you have to reach, keeping the list as small as is workable.
- Reboot and retest against a partner that was previously failing.
- Amend the baseline itself, because it will be reapplied at the next policy refresh and undo you.
The build cannot negotiate what the far end requires
You have this one if The registry values are correct, the server still cannot agree a suite, and no updates are published for the version you are on.
- Confirm the build with
Get-ExchangeServer | Format-List AdminDisplayVersionand compare it against what is currently supported. - Accept that configuration cannot add cipher suites the build does not implement.
- Plan the move to Exchange Server SE on a supported Windows Server build.
- In the interim, route the affected outbound mail through a host that can negotiate properly.
Full reference
Which direction the alert came from
| Event | Symbolic name | What it tells you |
|---|---|---|
| 36888 | SSLEVENT_GENERATE_FATAL_ALERT | This computer detected an error and generated the alert. Your side rejected their offer |
| 36887 | SSLEVENT_RECEIVE_FATAL_ALERT | This computer received a fatal alert from the far end. They rejected your offer |
| 36874 | – | A connection request arrived and none of the cipher suites the client supports are supported by this server |
| 36871 | – | A fatal error occurred while creating a TLS credential, which is a certificate or key fault rather than a suite mismatch |
Support state, and what it decides
| Fact | Where it leaves you |
|---|---|
| Exchange Server 2016 and 2019 reached end of support on 14 October 2025 | No further updates, so no further cipher suite or protocol changes |
| Exchange Server SE is the current on-premises product | Supported on Windows Server 2019, 2022 and 2025 |
| TLS 1.2 arrived in Exchange 2013 CU19 and Exchange 2016 CU8 | Anything below those cumulative updates cannot be configured into TLS 1.2 |
| Exchange Server 2019 supports TLS 1.2 by default | A failure there is configuration or hardening, not capability |
Applying the registry changes without locking yourself out
- Export every key you are about to touch, to a file on a share you can reach from elsewhere.
- Confirm you have console or out-of-band access to the server that does not depend on TLS from your workstation.
- Make the protocol changes, reboot, and test before touching the .NET values.
- Make the .NET changes, reboot again, and test the specific managed component that was failing.
- Only then retire older protocol versions, one at a time, testing between each.
Inventory what submits mail to the server before you disable an old protocol. Scanners, copiers and line-of-business applications are the devices that discover a protocol retirement by outage, and they are never the ones anyone remembers.
When the far end is Microsoft 365
- You will see event 36887 rather than 36888, because they are the ones rejecting.
- There is no configuration on their side to change and no exception to request.
- The minimum they accept has moved before and will move again, so a server that is only just current today is a problem you have deferred rather than solved.
- Routing affected outbound mail through a modern host is a legitimate interim measure, not a fix.
- Check the hybrid connectivity components separately from mail flow. They are managed code and they read the .NET values, not just the Schannel ones.
When a licence is the actual fix
If the build is past end of support, this stops being a configuration problem with a configuration answer. Exchange Server 2016 and Exchange Server 2019 both reached end of support on 14 October 2025, and an unsupported build receives no updates, so as Microsoft 365 continues to raise its minimum the gap only widens. Exchange Server SE is the current on-premises product and is supported on Windows Server 2019, 2022 and 2025. The server licence is one part of it: you also need client access licences for your users or devices, and a supported Windows Server underneath. We can work out which combination covers your organisation, including whether moving the mailboxes to Microsoft 365 costs less than relicensing the on-premises estate, and neither answer is automatic.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
0x80090331 |
SEC_E_ALGORITHM_MISMATCH: the client and server cannot communicate because they do not possess a common algorithm | Microsoft Learn |
Event ID 36888 |
SSLEVENT_GENERATE_FATAL_ALERT: this computer detected an error condition and generated a fatal alert to notify the other party | Microsoft Learn |
Event ID 36887 |
SSLEVENT_RECEIVE_FATAL_ALERT: this computer received a fatal TLS or SSL alert from the server it was negotiating with | Microsoft Learn |
Confirm the fix worked
- The registry values read back correctly under both the Client and Server subkeys, and in both .NET framework paths.
- The server has been rebooted since the change, because the configuration is not active until it has.
- No new fatal alert events appear in the system log for the partner that was failing.
- A test message through the connector that was failing is delivered.
- Internal submission from devices and applications still works after any protocol you retired.
Questions people ask about this
Can I fix this purely in the registry?
Only if the build supports the protocols and suites the far end requires and they are simply switched off. TLS 1.2 arrived in Exchange 2013 CU19 and Exchange 2016 CU8; below those, no registry value creates capability the code does not have.
Do I have to reboot?
Yes. Microsoft states the Exchange TLS configuration becomes active only after the server is restarted, and a half-applied change is the source of most of the confusing intermittent results people report.
Is it safe to enable TLS 1.2 on an old server?
Enabling it is the right direction, but on an out-of-support build you are setting one value on a server that receives no security fixes at all. It resolves the handshake and leaves the larger exposure untouched.
Do I have to buy anything to solve this?
If your build is supported, no: this is registry configuration and a reboot. If it is not, then yes, honestly, because no amount of configuration adds capability the code does not have.
Will disabling old protocols break my internal clients?
It can, particularly older scanners and copiers that submit mail. Inventory what submits to the server before retiring a protocol, rather than discovering those devices by outage.
