When I was developing an interface between a system using REST and a system using SOAP, suddenly I could not connect anymore to the SOAP test server.
I got the following cryptic error message:
I got the following cryptic error message:
{:error, %Mint.TransportError{ reason: {:tls_alert, {:unexpected_message, ~c"TLS client: In state hello_middlebox_assert at ssl_gen_statem.erl:807 generated CLIENT ALERT: Fatal - Unexpected Message\n {unexpected_msg,\n {internal,{encrypted_extensions,\#{alpn => {alpn,<<2,104,50>>}}}}}"}} }}
I was terrified with the idea that the production server started to reject my connections.
Searching for "TLS client: In state hello_middlebox_assert at ssl_gen_statem.erl" I found multiple references about issues related to Erlang, so my first approach was to try distinct Erlang and Elixir combinations.
I was using Req, which uses Finch, which in turn uses Mint, so I isolated the problem using the following mint_test.exs elixir script.
Mix.install( [ :castore, :mint ], force: true, verbose: true ) soap_server_url = "Here goes the SOAP server URL"
Mint.HTTP.connect(:https, soap_server_url, 443) |> dbg()
I ran it using Erlang 26.0.2 and Elixir 1.15.5-otp-24 and could reproduce the error easily.
Using asdf I installed multiple Erlang and Elixir versions until I found that the error disappeared when using
Erlang 24.3.2 and Elixir 1.14.5-otp-24.
Even though that solved the problem, I was not happy with the idea of being stuck with older versions of my development stack.
When running the above script I noticed that there was another message.
[warning] Description: ~c"Failed to assert middlebox server message" Reason: [missing: {:change_cipher_spec, 1}]
That lead me to think that perhaps the problem could be solved passing some options to Mint.HTTP.connect.
After trying a lot of options I finally reached to the following code:
Mix.install( [ :castore, :mint ], force: true, verbose: true ) soap_server_url = "Here goes the SOAP server URL without https://" opts = [ transport_opts: [ middlebox_comp_mode: false, ] ] Mint.HTTP.connect(:https, soap_server_url, 443, opts) |> dbg()
This code worked fine with every Erlang and Elixir combination that I tried.
The next step was to pass the options from Req to Mint which as it appears in the following script.
Mix.install( [ :req ], force: true, verbose: true ) soap_server_url = "https://" <> "Here goes the SOAP server URL" opts = [ transport_opts: [ middlebox_comp_mode: false ] ] req = Req.new(url: soap_server_url, connect_options: opts) Req.get(req) |> dbg()
That finally solved my problem.