Skip to content

Queue Fails to Delete with Orphaned Binding #1376

Closed as not planned
Closed as not planned
@LeeWhite187

Description

@LeeWhite187

Describe the bug

This bug is for v6.5.0 of the RabbitMQ.Client nuget package.
It's a queue binding registration problem that creates an exception on deletion of a queue.

The channel.QueueDelete method call in the .NET client library throws an exception with a message containing: 'NOT_FOUND - no exchange '.
This occurs if a previous add queue binding was attempted with an unknown exchange name.
The exception is erroneous, since the call is to delete a queue, and not an exchange.
So, that implies an orphaned reference, somewhere.... and the problem is not actually the queue delete call, directly.

It's actually that a previously executed channel.QueueBind method correctly fails with an exception for the missing exchange.
But is still allowed to register the binding (to a nonexistant exchange), before the throw.

And subsequently, when later, deleting a queue, the QueueDelete method call also throws an exception for the same missing exchange (and same exchange name).... because it discovers a binding for the missing exchange (that was allowed to be registered), even though no valid exchange existed (and the QueueBind call threw because of it).

This exception, on queue deletion, prevents the QueueDelete method logic from actually deleting the queue.
And, the queue has to be deleted via a REST call or through the management interface.

Reproduction steps

  1. Connect client to a RMQ cluster with a user context that has admin privileges.
  2. Create a Guid string that will be the name of a queue to be created.
  3. Create a Guid string that will represent an unknown exchange.
  4. Create a Guid string that will be the binding routing key.
  5. From the .NET client, create a queue with the Guid string from above.
  6. From the management interface, verify the queue was created.
  7. From the .NET client, create a queue binding using the queue name, exchange name, and routing key, created above.
  8. This will throw an exception because the exchange is NOT_Found.
  9. From the management interface, verify the queue binding is NOT present (though, it actually got registered before the throw).
  10. Query the REST API for the queue binding, and verify that it is NOT present (though, it actually got registered before the throw).
  11. From the .NET client, delete the queue by name.
  12. Verify it throws an exception for a NOT_Found exchange, with the Guid string of the unknown exchange in the exception message.
  13. From the management interface, verify the queue is still present, failing to be deleted.
  14. From the REST API, verify the queue is still present, failing to be deleted.

Expected behavior

The expected behavior is that:

The QueueBind method of the channel class must NOT register a binding or leave any dangling binding record when the given exchange name is not known, or the queue name is not known.

As well, the QueueDelete method of the channel must be intelligent enough to delete all bindings of the queue, regardless of exchange presence.
Also. The QueueDelete method should throw an exception for a not found queue, which it correctly does.
But, it should NOT throw an exception for a not found exchange, which is conceptually incorrect for a queue deletion.
It should gracefully cleanup any bindings without error.

Additional context

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions