Issue with using "amqp" package after upgrading to OTP26

After upgrading to OTP26, our app that uses amqp package fails to establish a connecting to RabbitMQ server, and I am failing to understand why. Connecting to OTP25 works fine.

# OTP25
AMQP.Connection.open("amqp://guest:guest@amqp-issue-rabbitmq")
{:ok, %AMQP.Connection{pid: #PID<0.241.0>}}
# OTP26
AMQP.Connection.open("amqp://guest:guest@amqp-issue-rabbitmq")
# => {:error, {:auth_failure, 'Disconnected'}}

I have a hunch this must be related to recent changes to SSL-specific defaults in OTP26. However, attempts to disable ssl_options doesnā€™t work either - it fails with another error, so I must be passing the options in a wrong way. For example, this fails:

AMQP.Connection.open("amqp://guest:guest@amqp-issue-rabbitmq", [ssl_options: :none])
# => {:error, :econnrefused}
Reproduction details

The reproduce script is this one:

# sample.bash
mix do local.hex --force, local.rebar --force

elixir -e 'Mix.install([:amqp]); AMQP.Connection.open("amqp://guest:guest@amqp-issue-rabbitmq") |> IO.inspect()'

The full reproduce experiment is this one:

docker network create amqp-issue

docker run \
  --rm \
  --name amqp-issue-rabbitmq \
  --detach \
  --network amqp-issue \
  rabbitmq:3.11.16-alpine

sleep 5 # give rabbitmq enough time to fully initialize

docker run \
  --rm \
  --name amqp-issue-otp25 \
  --network amqp-issue \
  --mount type=bind,source=$(realpath sample.bash),target=/tmp/sample.bash \
  hexpm/elixir:1.14.1-erlang-25.1.2-alpine-3.16.2 \
  ash /tmp/sample.bash

docker run \
  --rm \
  --name amqp-issue-otp25 \
  --network amqp-issue \
  --mount type=bind,source=$(realpath sample.bash),target=/tmp/sample.bash \
  hexpm/elixir:1.14.4-erlang-26.0-alpine-3.18.0 \
  ash /tmp/sample.bash

docker stop amqp-issue-rabbitmq

docker network rm amqp-issue

I havenā€™t dig too deep into amqp_client yet. Any ideas what might be preventing the connection and how to fix it? :thinking:

5 Likes

you must probably need to have a version of the server that supports otp26
for reference

2 Likes

you must probably need to have a version of the server that supports otp26

Would that not be somewhat counter-intuitive? I mean, since itā€™s a client thatā€™s having issues, and the only connection between client and server is done via TCP and using a well-establish message queue protocol :thinking:

The client implementation and the server share code, according to this note in that second Github issue:

Note that rabbit_net:port_command/2 is not only used by RabbitMQ server, but also by the AMQP 0.9.1 client. Therefore, instead of putting the OTP version (or send function) into persistent_term within the rabbit app, we just do it the first time rabbit_net:port_command/2 is invoked.

2 Likes

Fair enough :+1: Still canā€™t wrap my head around how that change would affect client in the connection scenario specifically though

:information_source: After upgrading to amqp_client 3.12.0, this issue is resolved now. Thereā€™s a chance connecting should also work with 3.11.17, but I wasnā€™t able to test that.

just updating the client worked for you? iā€™ve been using cloudamqp and their latest version is 3.9.X :pensive:

Just updating the client worked, yes. Iā€™m using cloudamqp too, and connecting using 3.12 client code appears to work now.

However, I only just did some quick tests. Havenā€™t deployed this yet.

2 Likes

In case someone else stumbles upon this thread: The documentation of the amqp library has an example which sets the fail_if_no_peer_cert to true (AMQP.Connection ā€” amqp v3.3.0)). Starting with OTP 26, setting this option on the client side will result in the error {:error, {:option, :server_only, :fail_if_no_peer_cert}}. See Erlang/OTP 26 Highlights - Erlang/OTP.

2 Likes