Resolving Common Windows TLS/SSL Security Errors
On Windows, the components use the TLS/SSL implementation of the operating system (Schannel) by default for TLS 1.2 and earlier. When Schannel fails to establish a connection, the error is reported with a Windows security error code in the 0x8009xxxx range. This entry describes the most common codes, their causes, and how to resolve them.
Using the Internal TLS Implementation
Many of these errors are caused by limitations of Schannel on the system, such as TLS versions, cipher suites, or certificate formats that the installed version of Windows does not support. In these cases, the error can often be resolved by using the internal TLS implementation of the components instead, which does not depend on the operating system. To do this, set the SSLProvider property to sslpInternal before connecting.
http.SSLProvider = HTTPSSLProviders.sslpInternal;
http.Get("https://www.example.com/");
When troubleshooting any of the errors below, the SSLStatus event also provides details about each step of the TLS handshake.
Error Codes
| Code | Message |
|---|---|
| 80090302 | The function requested is not supported. |
| 8009030D | The credentials supplied to the package were not recognized. |
| 8009030E | No credentials are available in the security package. |
| 80090304 | The Local Security Authority cannot be contacted. |
| 80090308 | The token supplied to the function is invalid. |
| 80090325 | The certificate chain was issued by an authority that is not trusted. |
| 80090326 | The message received was unexpected or badly formatted. |
| 80090327 | An unknown error occurred while processing the certificate. |
| 80090331 | The client and server cannot communicate, because they do not possess a common algorithm. |
| 8009035D | One or more of the parameters passed to the function was invalid. |
| 8009030F or 80090321 | The message or signature supplied for verification has been altered, or the buffers supplied to a function were too small. |
80090302
This error usually means that the client and server do not have a TLS version in common (e.g., the server requires TLS 1.2 or TLS 1.3, and it is not enabled on the client).
To resolve it, enable the TLS versions that the server supports using the SSLEnabledProtocols configuration setting. The value is the binary OR of the protocol values (192 for TLS 1.0, 768 for TLS 1.1, 3072 for TLS 1.2, and 12288 for TLS 1.3). For instance, to enable only TLS 1.2 and TLS 1.3:
http.Config("SSLEnabledProtocols=15360"); // TLS 1.2 (3072) + TLS 1.3 (12288).
If the version of Windows does not support the required TLS version, use the internal TLS implementation as described above.
8009030D
This error indicates that Schannel could not use the certificate that was provided for client or server authentication, which usually means that its private key is not accessible. Common causes and resolutions include:
- The certificate was loaded from a PEM file. Schannel requires the private key to be available in a Windows key store, so convert the certificate and key to a PFX (PKCS#12) file, or use the internal TLS implementation.
- The application does not have permission to access the private key. Grant the account that runs the application read access to the private key (e.g., using Manage Private Keys in the Certificates MMC snap-in).
- The application runs in IIS, and the application pool does not load the user profile. Set Load User Profile to True in the advanced settings of the application pool.
To convert a PEM certificate and key to a PFX file using OpenSSL:
openssl pkcs12 -export -in cert.pem -inkey key.pem -out cert.pfx -name "My Certificate"
Note that OpenSSL 3.0 and later encrypt PFX files with AES by default, which older versions of Windows (before Windows Server 2019 and Windows 10 version 1709) cannot read. To create a PFX file for these systems, add the -legacy option.
8009030E
This error indicates that the certificate has no private key that Schannel can use.
- Ensure that the certificate includes its private key (e.g., by loading it from a PFX file, or from a certificate store entry that has an associated private key).
- If the certificate is in the machine store, ensure that the account that runs the application can access the private key. Private keys for the machine store are located in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys (or C:\ProgramData\Microsoft\Crypto\Keys for keys stored by the CNG key storage provider).
- Ensure that the certificate is in the expected store (e.g., the MY store of the current user or of the local machine).
80090304
This error can occur when Schannel rejects the parameters of the key exchange (e.g., when the server uses Diffie-Hellman parameters that are shorter than the minimum length allowed by Windows).
- Ensure that the server uses modern key exchange parameters (e.g., ECDHE cipher suites, or Diffie-Hellman keys of at least 2048 bits).
- If the server cannot be changed, use the internal TLS implementation.
80090308
This error indicates that the handshake data received from the server was not valid. Common causes include:
- The server does not expect TLS on the current port. For servers that start TLS after connecting (e.g., FTP, SMTP, IMAP, or POP servers on their standard ports), set the SSLStartMode property to sslExplicit instead of sslImplicit.
- Some FTP servers require the PROT P command when using implicit TLS. In this case, set the UseProtWhenImplicit configuration setting of the FTP component to true.
- The server uses a certificate with a signature algorithm that Schannel does not support, or sends a very large number of CA certificates during the handshake. In this case, use the internal TLS implementation.
For more information, please see our TLS Handshake Error 80090308 entry.
80090325
This error indicates that the server's certificate chain could not be verified to a trusted root certificate authority (CA).
- Ensure that the server sends its full certificate chain (including intermediate certificates).
- Ensure that the root CA certificate is installed in the trusted root store of the client system.
For more information, please see our Resolving the "Server Certificate Verification Failed" Error entry.
80090326
This error indicates that the client and server could not agree on how to communicate, usually because of a protocol or cipher suite mismatch.
- Ensure that the TLS versions supported by the server are enabled using the SSLEnabledProtocols configuration setting.
- If the server requires a client certificate, ensure that the SSLCert property is set to a certificate with a private key.
- If the server does not support TLS session resumption, disable it using the ReuseSSLSession configuration setting (or the ReuseSSLSessionInDI configuration setting for FTP data connections).
- If the server requires TLS versions or cipher suites that are not supported by the version of Windows, use the internal TLS implementation.
80090327
This error indicates that the server could not process the client certificate, or that a required client certificate was not provided.
- Ensure that the certificate set in the SSLCert property is the one the server expects, and that it includes a private key.
- Use the SSLStatus event to see which certificates the server requests during the handshake.
80090331
This error indicates that the client and server do not have a cipher suite in common. It is most common on older versions of Windows, which do not support the cipher suites required by servers with modern security requirements.
- Update the system, or use the internal TLS implementation, which supports modern cipher suites on all versions of Windows.
- If specific cipher suites are restricted on the system by Group Policy or by registry settings, ensure that at least one cipher suite supported by the server is allowed.
8009035D
This error can occur when Windows rejects a weak security parameter during the handshake (e.g., a Diffie-Hellman key that is shorter than the minimum length allowed by Windows), and has also been associated with specific Windows updates.
- Ensure that the server uses modern key exchange parameters (e.g., ECDHE cipher suites, or Diffie-Hellman keys of at least 2048 bits).
- If the server cannot be changed, use the internal TLS implementation.
8009030F or 80090321
These errors are known to occur on Windows 8.1 and Windows Server 2012 R2 when certain DHE cipher suites are negotiated with TLS 1.2.
- Use the internal TLS implementation.
- Alternatively, update Windows, or disable the affected DHE cipher suites on the system.
Note that older versions of the components used the UseInternalSecurityAPI configuration setting to select the internal TLS implementation. This setting is still supported, but the SSLProvider property is now the recommended way to select the TLS implementation.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.