[rabbitmq-discuss] Stuck waiting for frame during amqp_basic_qos?

David Wragg david at rabbitmq.com
Wed Nov 9 22:19:18 GMT 2011

Hi Pieter,

Pieter de Zwart <pdezwart at rubiconproject.com> writes:
> I have managed to reproduce it using C code only. Caveat: this code is
> really messy and leaks like a sieve.
> Let me know what you think. And please don¹t judge me =)

Thanks.  That was very helpful to work out what is going on here.

Here's the tracer output with your program:

1320874543711: <Tracer-0> ch#1 -> {#method<basic.ack>(delivery-tag=22,multiple=true),null,""}
1320874543711: <Tracer-0> ch#1 -> {#method<basic.qos>(prefetch-size=0,prefetch-count=3, global=false),null,""}
1320874543752: <Tracer-0> ch#1 <- {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 22, class-id=60, method-id=80),null,""}
1320874543791: <Tracer-0> ch#1 -> {#method<basic.qos>(prefetch-size=0,prefetch-count=1, global=false),null,""}

The client sends the bad ack, and immediately follows up with the
basic.qos.  That first amqp_basic_qos call after the ack does return
NULL to indicate an error, although your program doesn't report that

Then your program does another basic.qos.  And the server never replies
to it.  That's actually what the AMQP spec requires: Once a peer sends a
channel.close, it should ignore all frames on that channel except the
channel.close-ok indicating that the channel is fully closed.

However, librabbitmq never sends a channel.close-ok, and in fact provides
no way to do so.

That seems like a bug in librabbitmq to me.  But I'll have to have a
think about the best way to fix it.

In the meanwhile, you should always check for errors from API calls.
When you get an error, you should not re-use the relevant channel.  And
if your connection is potentially long-lived, that means that you should
probably close and re-open it.

David Wragg
Staff Engineer, RabbitMQ
VMware, Inc.

More information about the rabbitmq-discuss mailing list