Hello!
I’m working on a piece of software with the requirement that I use a FIPS-approved encryption module. I’ve built OpenSSL 3.6.0 with 3.1.2 as a FIPS provider:
$ openssl list --providers
Providers:
fips
name: OpenSSL FIPS Provider
version: 3.1.2
status: active
Erlang has also been built with FIPS enabled:
Erlang/OTP 28 [erts-16.2] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]
Eshell V16.2 (press Ctrl+G to abort, type help(). for help)
1> application:load({application, crypto, [{env, [{fips_mode, true}]}]}), application:start(crypto).
ok
2> crypto:info_fips().
enabled
The problem is that mix deps.get refuses to work, and I kinda feel like it’s a misconfiguration of repo.hex.pm, but I really have no idea. I can successfully make requests to it as long as I manually pass middlebox_comp_mode: false, but there’s I don’t know if it’s even possible to do that with things like mix and libraries I need to use.
Nrap is just to test this issue, no other code except what’s included in a default mix project
mix.exs
defmodule Nrap.MixProject do
use Mix.Project
def project do
[
app: :nrap,
version: "0.1.0",
elixir: "~> 1.19",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:req, "~> 0.5.16"}
]
end
end
config/config.exs
import Config
config :crypto,
fips_mode: true
$ mix deps.get
Failed to fetch record for telemetry from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for finch from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for hpax from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for mint from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for mime from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for nimble_options from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for req from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for nimble_pool from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for jason from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Resolving Hex dependencies...
Failed to fetch record for plug from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for brotli from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for ezstd from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for nimble_csv from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for decimal from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
Failed to fetch record for castore from registry (using cache instead)
{:failed_connect, [{:to_address, {~c"repo.hex.pm", 443}}, {:inet, [:inet], {:options, {:insufficient_crypto_support, {:"tlsv1.1", {:versions, [:"tlsv1.2", :"tlsv1.1", :tlsv1]}}}}}]}
iex -S mix
Breaks added for readability
Erlang/OTP 28 [erts-16.2] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]
Interactive Elixir (1.19.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Req.get("https://google.com")
11:17:11.770 [debug] redirecting to https://www.google.com/
{:ok,
%Req.Response{
status: 200,
...
}}
iex(2)> Req.get("https://repo.hex.pm")
11:18:00.602 [warning] Description: ~c"Failed to assert middlebox server message"
Reason: [missing: {:change_cipher_spec, 1}]
Location: tls_client_connection_1_3.erl:344
11:18:00.604 [notice] TLS :client: In state :hello_retry_middlebox_assert at ssl_gen_statem.erl:755 generated CLIENT ALERT: Fatal - Unexpected Message
- {:unexpected_msg,
{:internal,
{:server_hello, {3, 3},
<<...>>,
<<...>>,
<<...>>,
%{
server_hello_selected_version: {:server_hello_selected_version, {3, 4}},
pre_shared_key: :undefined,
key_share: {:key_share_server_hello,
{:key_share_entry, :secp384r1,
<<...>>}}
}}}}
{:error,
%Req.TransportError{
reason: {:tls_alert,
{:unexpected_message,
~c"TLS client: In state hello_retry_middlebox_assert at ssl_gen_statem.erl:755 generated CLIENT ALERT: Fatal - Unexpected Message\n {unexpected_msg,\n {internal,\n {server_hello,\n {3,3},\n <<...>>,\n <<...>>,\n <<19,1>>,\n \#{server_hello_selected_version =>\n {server_hello_selected_version,{3,4}},\n pre_shared_key => undefined,\n key_share =>\n {key_share_server_hello,\n {key_share_entry,secp384r1,<<...>>}}}}}}"}}
iex(3)> Req.get("https://repo.hex.pm", connect_options: [transport_opts: [middlebox_comp_mode: false]])
{:ok,
%Req.Response{
status: 200,
headers: %{
"connection" => ["keep-alive"],
"content-type" => ["text/plain; charset=utf8"],
"date" => ["Tue, 16 Dec 2025 17:19:54 GMT"],
"x-served-by" => ["cache-chi-kigq8000103-CHI"]
},
body: "Everything's Okay",
trailers: %{},
private: %{}
}}
Some related issues that I haven’t been able to pull anything useful from:
Sorry if this is too much!
I would really appreciate any help on this, I’m a bit stuck ![]()
edit:
On further review this probably isnt relevant to us after all, as SC.L2-3.13.11 does not require the application to use FIPS-approved modules internally. I hope this helps some other poor soul out there.






















