Unity TLS 1.3 Websocket handshake

,

UnityWebRequest and ClientWebSocket fail to connect to a TLS 1.3-only server in Unity 6000.6.2f1, although the 6000.6.0 release notes state TLS 1.3 support

Thanks for reporting this!

UnityWebRequest regressed with our last Curl update, it looks like, since it used to work with TLS 1.3-only hosts. I’ll have this fixed soon. In the meantime, System.Net.Http.HttpClient should work correctly in that scenario.

For ClientWebSocket, that’s admittedly something we never tested for our TLS 1.3 coverage. I had a brief look and it seems Mono is hardcoding TLS 1.2 for that. I’ll patch it. In the meantime I’m not sure there’s any easy workaround. You could establish a connection with TcpClient/SslStream, do the HTTP upgrade manually, and then use WebSocket.CreateFromStream. Another option would be to use the websocket-sharp library which doesn’t depend on the WebSocket support in .NET.

Hi Simon,

Thank you for investigating this and confirming the issue.

We performed additional validation in our environment and can consistently reproduce the behavior:

  • Unity 6000.6.2f1 fails when connecting to a TLS 1.3-only Azure Application Gateway.
  • UnityWebRequest throws “Unable to complete SSL connection”.
  • WebSocket connections also fail against the same TLS 1.3-only endpoint.
  • On the same machine, using the same network and authentication token, a .NET 8 HttpClient and ClientWebSocket successfully connect to the same HTTPS and WSS endpoints.

This aligns with your findings regarding the UnityWebRequest regression and the ClientWebSocket TLS 1.2 limitation.

Our production environment is moving towards TLS 1.3-only enforcement, so understanding the timeline is important for our planning.

Could you please clarify:

  1. Has an internal fix already been submitted for both the UnityWebRequest and ClientWebSocket issues?
  2. Is there a bug ID, issue tracker, or public ticket that we can monitor?
  3. Do you expect the fix to be delivered in a future 6000.6 LTS patch release, and if so, do you have an estimated timeframe or target release version?
  4. Until the fix is available, would you recommend HttpClient and websocket-sharp as the preferred workarounds for TLS 1.3-only environments?

We appreciate your help and any guidance you can provide regarding the expected timeline, as it will help us determine whether we should implement a temporary workaround or wait for the official fix.

Thank you.

Has an internal fix already been submitted for both the UnityWebRequest and ClientWebSocket issues?

Yes, fixes for both issues are on their way to land.

Is there a bug ID, issue tracker, or public ticket that we can monitor?

No, I haven’t filed anything public-facing, but I’ll be posting updates here. If you really need bugs to track, you can file reports and I’ll keep those updated too. Please post the IDs here if you do file bugs.

Do you expect the fix to be delivered in a future 6000.6 LTS patch release, and if so, do you have an estimated timeframe or target release version?

Note that 6000.6 is not an LTS version. Its support ends in November. I’ll push for the fixes to make it there, but with its end-of-life being soon I can’t guarantee it. Fixes will definitely be included in 6000.3 and 6000.7 (both LTS versions), and also in 7000.0. I’ll post here once I know the exact versions. (Edit 2026-10-19: Don’t know why I listed 6.3 here; that version doesn’t even support TLS 1.3.)

In terms of timelines, I unfortunately can’t offer anything more precise than “a few weeks” at this point. UnityWebRequest fix should be out relatively soon, but ClientWebSocket needs a Mono update which might take a bit more time. Again, I’ll post here when I have more clarity on this.

Until the fix is available, would you recommend HttpClient and websocket-sharp as the preferred workarounds for TLS 1.3-only environments?

Yes, those would be my recommendations.

I just hit this issue today. I am getting a TLS failure from the overpass server:

I tried re-writing the requests using the dot net System.Net.Http.HttpClient but I’m still getting exceptions relating to TLS

Can you give more details on the errors you’re getting using HttpClient? I just tried on my end using Unity 6000.6.4f1 and I get a successful handshake and 200 response on https://overpass-api.de/. I tried a few other paths like /api/status and also get a successful TLS handshake (but 502 responses).

The server is indeed TLS 1.3 only though, so UnityWebRequest not working is expected until the fix above lands.

I’m on 6000.3.9f1

The exceptions are:

InnerException = {HttpRequestException} System.Net.Http.HttpRequestException: An error occurred while sending the request ---> System.Net.WebException: Error: SecureChannelFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException: Authenti…
 Data = ListDictionaryInternal
 HResult = {int} -2146233088
 HelpLink = {string} null
 InnerException = {WebException} System.Net.WebException: Error: SecureChannelFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> Mono.Security.Interface.TlsException: Handshak…
  Data = ListDictionaryInternal
  HResult = {int} -2146233079
  HelpLink = {string} null
  InnerException = {AuthenticationException} System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> Mono.Security.Interface.TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_NOT_DONE\r\n  at Mono.U…
   Data = ListDictionaryInternal
   HResult = {int} -2146233087
   HelpLink = {string} null
   InnerException = {TlsException} Mono.Security.Interface.TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_NOT_DONE\r\n  at Mono.Unity.Debug.CheckAndThrow (Mono.Unity.UnityTls+unitytls_errorstate errorState, Mono.Unity.UnityTls+unitytl…

The URI is:

https://overpass-api.de/api/interpreter

It’s a POST request, and the content / query is:

[out:json]
[timeout:120][date:"2026-06-06T00:00:00.0000000"];
(
    way(poly:"50.602892 30.843140 50.626044 30.843140 50.626044 30.879382 50.602892 30.879382");
    relation(poly:"50.602892 30.843140 50.626044 30.843140 50.626044 30.879382 50.602892 30.879382");
    node(poly:"50.602892 30.843140 50.626044 30.843140 50.626044 30.879382 50.602892 30.879382");
    way(r);
);
out geom;

My code is running in a coroutine. Here is the relevant part:


using HttpClient client = new();
StringContent content = new(query);
float retryTime = 30f;
bool retry = true;
while (retry)
{
    HttpRequestMessage request = new(HttpMethod.Post, overpass);
    request.Content = content;
    request.Headers.UserAgent.Add(UserAgent);
    Task<HttpResponseMessage> response = client.SendAsync(request);
    yield return new WaitUntil(() => response.IsCompleted);
    if (response.Result.StatusCode != HttpStatusCode.OK) // <--- it throws here on the lookup of response.Result

If I pass the same query from the command line using curl it works as expected.

That version doesn’t have support for TLS 1.3. Support for that landed in 6.6 and was not backported.

What about System.Net.Http.HttpClient?

Same thing, unfortunately. Both UnityWebRequest and HttpClient use the same TLS implementation under the hood.

Best HTTP bundle plug in?

I’m not familiar with this plugin’s details, so can’t comment on its suitability here. It does seem to be using a separate TLS stack that advertises support for both TLS 1.2 and 1.3, so it at least looks like it could be a good fit for you.

It appears to be working for us. :face_exhaling:

Hi Simon,

Thanks for the clarification and the update.

It’s good to know that fixes for both issues are already underway and planned for 6000.3 LTS, 6000.7 LTS, and 7000.0. In the meantime, we’ll evaluate HttpClient and websocket-sharp as temporary workarounds for our TLS 1.3-only environment.

Please keep us posted when the target versions are confirmed or when preview builds containing the fixes become available.

Thanks again for your support.

Not for 6000.3. That version doesn’t have TLS 1.3 at all. But you can use the plug-in Best HTTP Bundle to get around it. You will have to rewrite all of your web requests to use the plug in though.