Skip to content

[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

@YukiNuno12

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.

  • HttpWebRequest is affected, because it always sets RemoteCertificateValidationCallback internally.
  • Third-party libraries that pass a validation callback to SslStream (e.g. MailKit) fail in the same way.
  • HttpClient with the default handler (AndroidMessageHandler) is not affected, as it does not go through SslStream.

Reproduction Steps

  1. Build an Android app targeting .NET 11 (Preview 4 or later; also reproduced with RC 2).
  2. On an Android 9 (API 28) device, open a TLS connection to an HTTPS server using HttpWebRequest, or using SslStream with a RemoteCertificateValidationCallback.
  3. 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 HttpClient with the default handler (AndroidMessageHandler) avoids the issue, as it does not go through SslStream.
  • For direct SslStream usage, not passing a RemoteCertificateValidationCallback avoids the new code path.
  • No workaround is known for code paths where the callback cannot be removed, such as HttpWebRequest or 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

  1. 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.

  2. During the handshake, SSLStreamGetCipherSuite reads the cipher suite from getHandshakeSession(). On Android 9 this returns SSL_NULL_WITH_NULL_NULL, which is not a member of TlsCipherSuite, so Enum.Parse in SslConnectionInfo.Android.cs throws.

  3. 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

Related

Activity

  1. dotnet-policy-service commented on Oct 25, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
    See info in area-owners.md if you want to be subscribed.

  2. dotnet-policy-service commented on Oct 25, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-android': @vitek-karas, @simonrozsival, @steveisok, @akoeplinger
    See info in area-owners.md if you want to be subscribed.

  3. wfurt commented on Oct 26, 2026

    @wfurt
    Member

    we should take a look. As recent regression, this may need servicing.

  4. removed
    untriagedNew issue has not been triaged by the area owner
    on Oct 26, 2026
  5. added this to the 12.0.0 milestone on Oct 26, 2026
  6. simonrozsival commented on Oct 27, 2026

    @simonrozsival
    Member

    I'm looking into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions