Repository navigation
[Android] SslStream on Android 9 (API 28) fails with ArgumentException "SSL_NULL_WITH_NULL_NULL" since .NET 11 Preview 4 — is this expected? #136456
Description
Description
Since .NET 11 Preview 4, TLS connections through SslStream fail on Android 9 (API 28) when a RemoteCertificateValidationCallback is set. The handshake fails with an inner ArgumentException: Requested value 'SSL_NULL_WITH_NULL_NULL' was not found.
The same code works on .NET 11 Preview 3 and on .NET 10 on the same Android 9 device. It also works on Android 10 and later with .NET 11.
We would like to confirm whether this is expected behavior, or a regression.
HttpWebRequestis affected, because it always setsRemoteCertificateValidationCallbackinternally.- Third-party libraries that pass a validation callback to
SslStream(e.g. MailKit) fail in the same way. HttpClientwith the default handler (AndroidMessageHandler) is not affected, as it does not go throughSslStream.
Reproduction Steps
- Build an Android app targeting .NET 11 (Preview 4 or later; also reproduced with RC 2).
- On an Android 9 (API 28) device, open a TLS connection to an HTTPS server using
HttpWebRequest, or usingSslStreamwith aRemoteCertificateValidationCallback. - The handshake fails with the exception shown below.
Running the same app built with .NET 11 Preview 3 or .NET 10 on the same device succeeds.
A minimal repro can be provided if needed.
Expected behavior
The TLS handshake succeeds on Android 9 (API 28), as it does with .NET 10 and .NET 11 Preview 3.
Actual behavior
The TLS handshake fails with the following exception:
System.Net.WebException: The SSL connection could not be established, see inner exception.
---> System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ArgumentException: Requested value 'SSL_NULL_WITH_NULL_NULL' was not found.
at System.Enum.TryParseByName[UInt16](RuntimeType enumType, ReadOnlySpan`1 value, Boolean ignoreCase, Boolean throwOnFailure, UInt16& result)
at System.Enum.TryParseByValueOrName[UInt16,UInt16](RuntimeType enumType, ReadOnlySpan`1 value, Boolean ignoreCase, Boolean throwOnFailure, UInt16& result)
at System.Enum.Parse[TlsCipherSuite](String value, Boolean ignoreCase)
at System.Enum.Parse[TlsCipherSuite](String value)
at System.Net.Security.SslConnectionInfo.UpdateSslConnectionInfo(SafeSslHandle sslContext)
at System.Net.Security.SslStreamPal.QueryContextConnectionInfo(SafeDeleteSslContext securityContext, SslConnectionInfo& connectionInfo)
at System.Net.Security.SslStream.VerifyRemoteCertificateCore(...)
at System.Net.Security.SslStream.VerifyRemoteCertificate(...)
at System.Net.Security.SslStream.VerifyRemoteCertificate(IntPtr platformValidationError)
at System.Net.Security.SslStream.JavaProxy.VerifyRemoteCertificate(IntPtr sslStreamProxyHandle, IntPtr platformValidationError)
--- End of inner exception stack trace ---
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](...)
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(...)
Regression?
Yes.
| Runtime | Android 9 (API 28) | Android 10+ |
|---|---|---|
| .NET 10 | OK | OK |
| .NET 11 Preview 3 (11.0.0-preview.3.26207.106) | OK | – |
| .NET 11 Preview 4 (11.0.0-preview.4.26230.115) | Fails | – |
| .NET 11 RC 2 (11.0.0-rc.2.26504.105) | Fails | OK |
Known Workarounds
- For HTTP, using
HttpClientwith the default handler (AndroidMessageHandler) avoids the issue, as it does not go throughSslStream. - For direct
SslStreamusage, not passing aRemoteCertificateValidationCallbackavoids the new code path. - No workaround is known for code paths where the callback cannot be removed, such as
HttpWebRequestor STARTTLS in third-party libraries.
Configuration
- .NET SDK: 11.0.100-rc.2.26504.105
- Android workload: 37.2.0-rc.2.84
- Device: Android 9 (API 28), physical device
Other information
Our analysis
-
Support certificate validation TLS alerts for Linux #115996 added the following branch to
SslStream.Protocol.cs, which is included from Preview 4 (confirmed against the release tags):if (connectionInfo.Protocol == 0 && securityContext is not null) { SslStreamPal.QueryContextConnectionInfo(securityContext, ref connectionInfo); }
On Android, certificate validation is invoked from the Java trust manager during the handshake, so this now queries the cipher suite before the handshake has completed.
-
During the handshake,
SSLStreamGetCipherSuitereads the cipher suite fromgetHandshakeSession(). On Android 9 this returnsSSL_NULL_WITH_NULL_NULL, which is not a member ofTlsCipherSuite, soEnum.ParseinSslConnectionInfo.Android.csthrows. -
Our understanding is that this OS difference comes from BoringSSL changing
SSL_get_current_cipher()in google/boringssl@384d0eaf (2018-11). We have not verified this against the AOSP sources for Android 9.
Relation to #136272
#136272 skips the early connection-info query on API 27 only, to avoid the native SIGSEGV reported in #135094. As its description notes, API 28 has the null check in Conscrypt, so API 28 does not crash. However, on API 28 the null cipher is returned as SSL_NULL_WITH_NULL_NULL, and the early query still fails in managed code with the ArgumentException above. With the current condition in #136272, API 28 would remain affected.
Questions
- Is this failure on Android 9 expected with the change in Support certificate validation TLS alerts for Linux #115996?
- If it is not expected, could the fix in Avoid early TLS connection-info queries on Android 8.1 #136272 (or a separate fix) cover API 28 as well? For example, skipping the early query below API 29, or treating an unknown cipher suite name as unknown instead of throwing.
- Is a fix planned for .NET 11?
Activity
dotnet-policy-service commentedon Oct 25, 2026
Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Oct 25, 2026
Tagging subscribers to 'arch-android': @vitek-karas, @simonrozsival, @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.
wfurt commentedon Oct 26, 2026
we should take a look. As recent regression, this may need servicing.
simonrozsival commentedon Oct 27, 2026
I'm looking into it