RabbitMqServer fails to start against RabbitMQ 4.4.0 with its default configuration. RabbitMQ now refuses queues that are neither durable nor exclusive, and ServiceStack declares one such queue mq:<Message>.outq, for every registered message type.
What we see
RabbitMQ 4.4.0 on Erlang/OTP 28, default configuration. Our services register handlers with RegisterHandler<T> and call Start().
RabbitMQ’s log:
Feature `transient_nonexcl_queues` is deprecated. By default, this feature is not permitted anymore.
operation queue.declare caused a connection exception internal_error
The client:
RabbitMQ.Client.Exceptions.OperationInterruptedException: ... code=541, text='INTERNAL_ERROR - Feature transient_nonexcl_queues is deprecated.
We get the same result with ServiceStack.RabbitMq 10.4.2 on .NET 10 and with 6.0.2 on .NET Framework 4.8.1. Both work on RabbitMQ 3.13.
Where it comes from
RegisterTopic in ServiceStack.RabbitMq/RabbitMqExtensions.cs on main:
channel.QueueDeclare(queueName, durable: false, exclusive: false, autoDelete: false, arguments: args);
RegisterQueues always calls it for QueueNames<T>.Out. As far as I can see, there is no way to change this from outside:
CreateTopicFilterreceives only the arguments dictionary, not thedurableorexclusiveflags.DisablePublishingToOutq = truestops messages being published to.outq, but the queue is still declared. We already set this, because nothing in our application reads.outq.
Workaround
Adding this to rabbitmq.conf lets everything run on 4.4.0:
deprecated_features.permit.transient_nonexcl_queues = true
RabbitMQ’s log says the feature will be removed in a future major version, so this only buys time. RabbitMQ 3.13 is out of community support, which is why we are moving to 4.x.
What would help
Either of these would let ServiceStack run on RabbitMQ 4.4 as installed:
- Do not declare
.outqwhenDisablePublishingToOutqis true, or add a setting that skips topic queues. - A setting, or a filter that can set the flags, so
.outqcan be declared durable.
One question for existing installations: brokers that already hold transient mq:*.outq queues cannot have them redeclared as durable, since RabbitMQ rejects a redeclaration with different properties. Would you expect applications to delete those queues on upgrade, or would ServiceStack handle it?
Is there a supported way to do this today that I’m missing? If not, could it be considered for an upcoming release? I am happy to test a pre-release build against 4.4.