Unexpected connection closure when declaring exchange with invalid exchange-type

653 views
Skip to first unread message

vitaly numenta

unread,
May 27, 2015, 6:22:04 PM5/27/15
to rabbitm...@googlegroups.com
running RabbitMQ 3.5.x on Mac OS X

exchange.declare with invalid exchange-type (e.g., "www") results in closing of the Connection: 503, "COMMAND_INVALID - unknown exchange type 'www'", 40, 10

Normally, errors on the channel are signaled by closing the channel. Why is the connection closed in this case in stead of the channel? That sound quite extreme.

Many thanks,
Vitaly

Michael Klishin

unread,
May 27, 2015, 8:01:17 PM5/27/15
to rabbitm...@googlegroups.com, vitaly numenta
On 28 May 2015 at 01:22:06, vitaly numenta (vitaly.kru...@gmail.com) wrote:
> exchange.declare with invalid exchange-type (e.g., "www")
> results in closing of the Connection: 503, "COMMAND_INVALID
> - unknown exchange type 'www'", 40, 10
>
> Normally, errors on the channel are signaled by closing the channel.
> Why is the connection closed in this case in stead of the channel?
> That sound quite extreme.

The spec is not particularly clear on how this kind of error must be handled. Specifying
an exchange type that does not conform to the standard can be seen as an unrecoverable
failures (and it is: unless the app is fixed, it will happen over and over).

Section 3.1.3.6  says:

«All non-normative exchange types MUST be named starting with "x-".»

There are other connection-level errors, e.g. invalid framing. 
--
MK

Staff Software Engineer, Pivotal/RabbitMQ


vitaly numenta

unread,
May 27, 2015, 8:40:42 PM5/27/15
to rabbitm...@googlegroups.com, vitaly.kru...@gmail.com
My 2-cents-worth is that something like bad framing potentially corrupts the connection for all channels and implies a systemic error in the client library, so it makes sense to close the connection in that case. For channel API errors, Channel.Close is an excellent mechanism that communicates all the same failure information, and seems more appropriate in this case. 

Michael Klishin

unread,
May 27, 2015, 8:44:22 PM5/27/15
to rabbitm...@googlegroups.com, vitaly numenta
Just to put things into perspective , incorrectly specified exchange type is typically not recoverable (an app
modification is needed). This is different from publishing to a non-existent exchange,
for example, which can be corrected by the app on the fly by declaring one.

The latter is also a reasonably common scenario. Incorrectly specified exchange type
isn't.

vitaly numenta

unread,
May 27, 2015, 8:46:25 PM5/27/15
to rabbitm...@googlegroups.com
[ended up posting prematurely somehow]

This is how AMQP 0.9.1 defines Channel.Close, which I think is in line with my argument:

This method indicates that the sender wants to close the channel. This may be due to internal conditions (e.g. a forced shut­down) or due to an error handling a specific method, i.e. an exception. When a close is due to an exception, the sender provides the class and method id of the method which caused the exception.

Michael Klishin

unread,
May 27, 2015, 8:49:10 PM5/27/15
to rabbitm...@googlegroups.com, vitaly numenta
On 28 May 2015 at 03:46:28, vitaly numenta (vitaly.kru...@gmail.com) wrote:
> This is how AMQP 0.9.1 defines Channel.Close, which I think
> is in line with my argument:

The spec defines two types of exceptions: soft and hard. Using an incorrect exchange
type is currently considered to be a "hard" failure. I tend to agree with this, even though
the classification is definitely quite subjective.

In any case, you are not likely to run into this exception often, and when you do,
noticing it as early as possible is probably a good idea. 

vitaly numenta

unread,
May 27, 2015, 8:49:42 PM5/27/15
to rabbitm...@googlegroups.com
I realize that a change in this regard is probably not going to happen (bigger priorities...), it just caught me a off-guard in the error-handling logic and struck me as quite arbitrary.
Message has been deleted

vitaly numenta

unread,
May 28, 2015, 4:36:38 AM5/28/15
to rabbitm...@googlegroups.com
Michael, it just occurred to me what is the real problem with using Connection.Close in this case instead of Channel.Close, and I think that it's quite serious: Let's assume that we have multiple channels open and operating over a single connection (e.g., multithreaded app, one thread per channel). 

When I issue a method on a channel and get a Channel.Close back, it's pretty easy to correlate the channel exception to the command issues on that channel.

On the other hand, a Connection.Close is not channel-specific, so we need clever voodoo on the client side to be able to *guess* which channel it might have applied to in order to track down the culprit and correlate the channel exception to the specific method invocation on a specific channel. This is unnecessarily difficult, and not entirely deterministic.

Michael Klishin

unread,
May 28, 2015, 4:52:01 AM5/28/15
to vitaly numenta, rabbitm...@googlegroups.com
Vitaly,

I don't have much to add. Using an incorrect exchange type is not a recoverable exception in practice.
The probability of running into it can be driven to effectively zero by performing validation in the clients and/or your application (if the type is user-provided).

While we probably can change this in the protocol because this is not a common error at all, there is no way an app can recover from it without a modification and redeployment (in practice, not in theory).

MK
--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-user...@googlegroups.com.
To post to this group, send email to rabbitm...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

vitaly numenta

unread,
May 28, 2015, 5:01:24 AM5/28/15
to rabbitm...@googlegroups.com, vitaly.kru...@gmail.com
Thanks Michael. I understand that in practice, if an app is running into an issue like this, the app will not recover from such a bug without intervention. Is it easy to identify in RabbitMQ code which other channel-specific errors would be reported via Connection.Close instead of Channel.Close? I just need a hint so I'll know where to look.

Best,
Vitaly

Michael Klishin

unread,
May 28, 2015, 5:03:52 AM5/28/15
to rabbitm...@googlegroups.com, vitaly numenta
On 28 May 2015 at 12:01:26, vitaly numenta (vitaly.kru...@gmail.com) wrote:
> Is it easy to identify in RabbitMQ code which other channel-specific
> errors would be reported via Connection.Close instead of Channel.Close?
> I just need a hint so I'll know where to look.

You have a hint in the erroneous exchange type ("www"). 

vitaly numenta

unread,
May 28, 2015, 12:15:01 PM5/28/15
to rabbitm...@googlegroups.com, vitaly.kru...@gmail.com
:) Sorry if my request was unclear (it was late here), I was asking for a hint on how to locate in the RabbitMQ source code all of the channel API errors that would result in Connection.Close instead of Channel.Close (not how to debug this specific instance of the issue).

Thanks again!

Michael Klishin

unread,
May 28, 2015, 1:17:56 PM5/28/15
to rabbitm...@googlegroups.com, vitaly numenta
Search for uses of the #'connection.close' record and rabbit_misc:amqp_error/4.
The majority of them are in rabbit_reader and rabbit_channel. 
Reply all
Reply to author
Forward
0 new messages