Fix it now
The connection is dying during the TLS handshake, below IIS, which is why there is nothing useful in the site log. Microsoft publishes Event ID 36870 as a fatal error accessing the TLS server credential private key, and attributes it to the keys in the MachineKeys folder not being readable. Start there.
certutil -store my
icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys
Get-TlsCipherSuite | Format-Table Name
- Open
certlm.msc, expand Personal then Certificates, find the certificate bound to the site, and confirm it reports a corresponding private key. - If the key association is broken, repair it:
certutil -repairstore my <thumbprint>. - Check the permissions on
C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. Microsoft’s documented remediation for 36870 grants Full control to NT AUTHORITY\System and BUILTIN\Administrators and Read to NT AUTHORITY\NETWORK SERVICE on that folder and its contents. - For a per-certificate fix instead, right-click the certificate, All Tasks, Manage Private Keys, and grant Read to the account the site or service runs as.
- If the handshake fails without any key problem, compare the cipher suites the two ends offer.
Get-TlsCipherSuitelists what this server will accept.
Take a copy of the current permissions before you change them. Microsoft’s own script writes the before and after state of the MachineKeys ACL to a file for exactly this reason.
If HTTPS is working again, stop here. If it is not, the next section separates a key problem from a negotiation problem, which have nothing in common but the symptom.
Why it happens
TLS termination happens below IIS. The kernel accepts the connection and Schannel negotiates the session using the certificate bound to that address, port and host name. Only once that succeeds does an HTTP request exist for IIS to route. That is why a handshake failure produces no useful entry in the IIS log at all: from the web server’s point of view, nothing ever arrived.
Event ID 36870 is the one Microsoft actually publishes, and it is worth reading carefully. The message is that a fatal error occurred when attempting to access the TLS server credential private key, with an error code from the cryptographic module. The documented cause is that the local RSA keys in the MachineKeys folder cannot be accessed, either because the permissions on that folder or on the individual key files are wrong, or because the key is corrupted or missing. Note where the fault is: not the certificate, the key.
Two other Schannel event IDs are quoted constantly for this, 36874 and 36886, and Microsoft does not publish a meaning for either. This article will not invent one. What is documented is the behaviour behind the symptom people attach to 36874: the client advertises its cipher suites in the Client Hello and the server returns its choice in the Server Hello, and if there are no matching suites the server closes the connection instead of sending a Server Hello at all. That is what a negotiation failure looks like on the wire, and it is diagnosable without knowing what any event ID is called.
The service cannot read the certificate’s private key
You have this one if 36870 at the moment a client connects, and the certificate is present and in date.
- Check the folder first:
icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys. Microsoft’s documented grant is Full control for NT AUTHORITY\System and BUILTIN\Administrators, and Read for NT AUTHORITY\NETWORK SERVICE. - For a single certificate, open
certlm.msc, find it under Personal, right-click, All Tasks, Manage Private Keys, and grant Read to the identity the site runs as. For an application pool identity use theIIS AppPool\<poolname>form. - If the Manage Private Keys dialog is unavailable, the certificate has no key associated. Run
certutil -repairstore my <thumbprint>and try again. - Restart the site or the affected service and reconnect.
Grant Read, not Full control. Full control on a private key is unnecessary and widens the damage if the service account is ever compromised.
The next fix edits the SCHANNEL keys under HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders. Export the branch first and change one thing at a time. A protocol misconfiguration here can lock you out of remote management on the same server, so have console access before you start.
Hardening left the two ends with nothing in common
You have this one if The failures started after a security change rather than after a certificate change, and older clients fail while a current browser succeeds.
- List what the server will actually offer:
Get-TlsCipherSuite. - Take a network trace and read the Client Hello and Server Hello. If there are no matching suites, the server closes the connection without sending a Server Hello, which is the signature you are looking for.
- Add a suite back with
Enable-TlsCipherSuite. Microsoft documents that no restart is required for that change to take effect. - For protocol versions, check each version’s Server and Client sub-keys under the SCHANNEL Protocols key, and reboot afterwards, because that configuration is read when Schannel starts.
- Check Group Policy as well. The SSL cipher suite order policy overrides local settings.
Inventory what still connects before disabling a protocol. Appliances, scanners and line-of-business clients update on their own schedule and will not tell you in advance.
Client certificate authentication is rejecting the caller
You have this one if An HTTP status rather than a Schannel event: 403.7, 403.16 or 403.17, on a site configured to require client certificates.
- 403.7 is published as client certificate required: the client sent none. Check it has one and is being offered the right issuer list.
- 403.16 is published as the client certificate being untrusted or invalid: install the issuing and intermediate certificates into the correct stores on the server.
- 403.17 is published as the client certificate having expired or not yet being valid: check the certificate dates and the clock on both machines.
- Confirm the revocation list the chain refers to is reachable from the server.
403.6 is published as IP address rejected. It is an address restriction rule and has nothing to do with certificates, so if that is what you are seeing, this whole article is the wrong one.
Full reference
Which of these Microsoft actually publishes
| Identifier | Status | What is published |
|---|---|---|
| Event ID 36870 | Published | A fatal error occurred when attempting to access the TLS server credential private key, with a cryptographic module error code. Cause: the RSA keys in the MachineKeys folder cannot be accessed |
| Event ID 36874 | Not published | No Microsoft page found that states a meaning. Read the event text on the machine |
| Event ID 36886 | Not published | No Microsoft page found that states a meaning |
403.6 |
Published | IP address rejected |
403.7 |
Published | Client certificate required |
403.16 |
Published | Client certificate is untrusted or invalid |
403.17 |
Published | Client certificate has expired or is not yet valid |
That table is the reason this article is shaped the way it is. Most treatments of this problem confidently assign meanings to 36874 and 36886, and those meanings may well be right, but they are not published, so they should not be the thing you plan a change window around. Diagnose from the certificate, the key, and the cipher suites, all three of which you can read directly.
The MachineKeys folder
Machine-scoped private keys live as files under C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys, and each one carries its own access control list. Import a certificate through a wizard, renew it through a different tool, or restore it from a backup, and the key can end up readable only by administrators. The service then finds the certificate, fails to open the key, and drops the connection. Microsoft’s documented remediation is:
| Principal | Grant |
|---|---|
NT AUTHORITY\System |
Full control |
BUILTIN\Administrators |
Full control |
NT AUTHORITY\NETWORK SERVICE |
Read |
Capture the current state with icacls C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys /t /c to a file before you change anything, and again afterwards. Microsoft’s own published script does both, which tells you how often this needs undoing.
Certificate store commands worth knowing
| Command | What it does |
|---|---|
certutil -store my |
Lists the certificates in the machine Personal store, with their thumbprints and key information |
certutil -repairstore my <thumbprint> |
Repairs a key association, or updates certificate properties or the key security descriptor |
Get-TlsCipherSuite |
Lists the cipher suites this machine will offer, in a readable form |
Enable-TlsCipherSuite -Name <suite> |
Adds a suite to the list. No restart is required |
Disable-TlsCipherSuite -Name <suite> |
Removes one |
certutil -repairstore takes a store name and a certificate match token, and a SHA-1 thumbprint is one of the documented forms of that token, which is why the usual invocation works. netsh http show sslcert is the other command people reach for here, to read the certificate hash bound to an address and port; it is standard but this article could not confirm it against a Microsoft page, so treat its output as a cross-check rather than as the authority.
Protocol and cipher configuration, and where it is read from
- Cipher suite changes through
Enable-TlsCipherSuiteandDisable-TlsCipherSuitetake effect without a restart. Microsoft states that explicitly. - Protocol version changes under the SCHANNEL Protocols registry branch are read when Schannel starts, so they do need a reboot.
- Group Policy wins. The SSL cipher suite order policy overrides local configuration, so a change that keeps reverting is a policy, not a bug.
- If a hardening tool or script made the original change, re-run it with a documented profile rather than unpicking individual values by hand. You will otherwise be doing this again after the next run.
When the certificate and the ciphers are both fine
- Confirm the binding actually points at the certificate you think it does, and that the host name in the binding matches what clients are asking for.
- Check the certificate chain from the client’s point of view, not the server’s. A server that trusts its own issuer tells you nothing about what a client sees.
- Check the clock on both ends before blaming the certificate dates.
- Remember that a wildcard or multi-domain certificate does not change any of this mechanically. What it changes is the blast radius: one unreadable key takes down every host name the certificate covers.
When a licence is the actual fix
Most of this costs nothing. Key permissions, bindings and cipher configuration are all free to fix on a supported server. The case where a licence genuinely becomes part of the answer is a server on a Windows release old enough that it cannot offer the protocol versions your clients, your auditors or your payment processor now insist on, because no amount of registry work adds a protocol the operating system does not implement. If that is where you are, the honest fix is a current platform, and Windows Server 2025 Standard is the usual replacement for a web-facing host. Arco can supply the licence and check whether the workload can move under an agreement you already hold before you buy a second one.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
Event ID 36870 |
A fatal error occurred when attempting to access the TLS server credential private key. Microsoft attributes it to the RSA keys in the MachineKeys folder being unreadable, or the key being corrupted or missing | Microsoft Learn |
Event ID 36874 |
A Schannel entry widely quoted for handshake failures. Microsoft publishes no meaning for it, so read the event text on the machine and diagnose the negotiation from the cipher suite lists on both ends | not published by the vendor |
HTTP 403.7 |
Client certificate required: the site requires one and none was presented | Microsoft Learn |
HTTP 403.6 |
IP address rejected: an address restriction rule refused the request, unrelated to TLS | Microsoft Learn |
Event ID 36886 |
Another Schannel entry with no published meaning. Read it on the machine, then confirm what certificate is actually bound before acting on anyone’s interpretation of it | not published by the vendor |
HTTP 403.16 |
Client certificate is untrusted or invalid | Microsoft Learn |
HTTP 403.17 |
Client certificate has expired or is not yet valid | Microsoft Learn |
Confirm the fix worked
- Connect to the site over HTTPS from a client that was previously failing and confirm the handshake completes.
- Check the System log for new Schannel entries after that test.
- Run
certutil -store myand confirm the certificate you expect is present with its private key. - Run
Get-TlsCipherSuiteand confirm the suites your required clients need are listed. - Restart the server and re-test, so you know the fix survives a reboot rather than living in a running process.
Questions people ask about this
Do I need a new certificate to fix 36870?
Usually not. Microsoft’s published cause is that the private key in the MachineKeys folder cannot be accessed, which is a permissions or key-association problem. Re-issuing a certificate sometimes fixes it by accident, which is why the myth persists. Check the key first.
What does Event ID 36874 mean?
Microsoft does not publish a meaning for it, and this article will not make one up. Diagnose the failure it usually accompanies directly: compare the cipher suites the client offers with what Get-TlsCipherSuite says the server will accept. If there is no overlap, the server closes the connection without sending a Server Hello.
Will disabling old TLS versions break anything?
It can. Inventory what still connects before you disable a protocol, particularly appliances, scanners and line-of-business clients that update on their own schedule. Protocol changes need a reboot; cipher suite changes do not.
Why is there nothing in the IIS log?
Because the failure happens before an HTTP request exists. Schannel negotiates below the web server, so the evidence is in the System event log rather than the site log. If you are getting an HTTP status such as 403.7 or 403.16, you are past the handshake and looking at a different problem.
Does a wildcard or multi-domain certificate change any of this?
Not mechanically. The key access control list, the binding and the cipher negotiation all work the same way. What changes is the blast radius: one unreadable key affects every host name the certificate covers.
