-
Notifications
You must be signed in to change notification settings - Fork 612
Description
Discussed in #1855
Originally posted by krisz2000 August 8, 2025
Describe the bug
Hi,
I'm trying to implement a rabbitmq connection that uses the ConnectionFactory with AutomaticRecoveryEnabled set to true. I was using code similar to what the documentation says. To make automatic recovery work I want to make sure that the first connection is created properly, so when a connection attempt fails I retry again after a 5 second delay. To simulate a rabbitmq that is unreachable I use a docker container running the latest image (rabbitmq:4.1.3-management). I start my dotnet service that tries to create the first connection at startup and as expected it fails at first with this exception:
> RabbitMQ connection creation failure.
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable
---> System.AggregateException: One or more errors occurred. (Connection failed, host 127.0.0.1:5672)
---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed, host 127.0.0.1:5672
---> System.Net.Sockets.SocketException (111): Connection refused
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|285_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
at RabbitMQ.Client.Impl.SocketFactory.ConnectUsingAddressFamilyAsync(IPEndPoint endpoint, Func`2 socketFactory, AddressFamily family, TimeSpan connectionTimeout, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at RabbitMQ.Client.Impl.SocketFactory.ConnectUsingAddressFamilyAsync(IPEndPoint endpoint, Func`2 socketFactory, AddressFamily family, TimeSpan connectionTimeout, CancellationToken cancellationToken)
at RabbitMQ.Client.Impl.SocketFactory.OpenAsync(AmqpTcpEndpoint amqpTcpEndpoint, Func`2 socketFactory, TimeSpan connectionTimeout, CancellationToken cancellationToken)
at RabbitMQ.Client.Impl.SocketFrameHandler.CreateAsync(AmqpTcpEndpoint amqpTcpEndpoint, Func`2 socketFactory, TimeSpan connectionTimeout, CancellationToken cancellationToken)
at RabbitMQ.Client.ConnectionFactory.CreateFrameHandlerAsync(AmqpTcpEndpoint endpoint, CancellationToken cancellationToken)
at RabbitMQ.Client.EndpointResolverExtensions.SelectOneAsync[T](IEndpointResolver resolver, Func`3 selector, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at RabbitMQ.Client.EndpointResolverExtensions.SelectOneAsync[T](IEndpointResolver resolver, Func`3 selector, CancellationToken cancellationToken)
at RabbitMQ.Client.Framing.AutorecoveringConnection.CreateAsync(ConnectionConfig config, IEndpointResolver endpoints, CancellationToken cancellationToken)
at RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(IEndpointResolver endpointResolver, String clientProvidedName, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(IEndpointResolver endpointResolver, String clientProvidedName, CancellationToken cancellationToken)
After I start the rabbitmq container again the following exception is thrown a couple of times
> RabbitMQConnection[0]
RabbitMQ connection creation failure.
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable
---> System.IO.IOException: connection.start was never received, likely due to a network timeout
---> System.IO.EndOfStreamException: Pipe is completed.
at RabbitMQ.Client.Impl.InboundFrame.ReadFromPipeAsync(PipeReader reader, UInt32 maxInboundMessageBodySize, InboundFrame frame, CancellationToken mainLoopCancellationToken)
at RabbitMQ.Client.Framing.Connection.ReceiveLoopAsync(CancellationToken mainLoopCancellationToken)
at RabbitMQ.Client.Framing.Connection.MainLoop()
--- End of inner exception stack trace ---
at RabbitMQ.Client.Framing.Connection.StartAndTuneAsync(CancellationToken cancellationToken)
at RabbitMQ.Client.Framing.Connection.OpenAsync(CancellationToken cancellationToken)
at RabbitMQ.Client.Framing.Connection.OpenAsync(CancellationToken cancellationToken)
at RabbitMQ.Client.Framing.AutorecoveringConnection.CreateAsync(ConnectionConfig config, IEndpointResolver endpoints, CancellationToken cancellationToken)
at RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(IEndpointResolver endpointResolver, String clientProvidedName, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(IEndpointResolver endpointResolver, String clientProvidedName, CancellationToken cancellationToken)
The end result is that when I check the rabbitmq management frontend I see multiple connections have been created by my service. These connections are kept alive by automatic recovery, but I have no way to access them because the factory threw an exception while creating them.
Is this a bug or am I missing something?
Reproduction steps
- Use the code found in the documentation for automatic connection recovery. In the retry logic try connecting again until a connection is created.
- Start the service while the rabbitmq container is not running. Wait a bit for some connection failures.
- Start the rabbitmq container
- Wait until the connection is created
- See that there are multiple connections in the rabbitmq management frontend.
Expected behavior
Only one rabbitmq connection should be created and kept alive by the factory
Additional context
Rabbitmq management version: 4.1.3
Rabbitmq dotnet client version: 7.1.2
Dotnet version: 8.0