Skip to content

Bug: robust_queue.bind on an expiring queue causes channel not found on same cases #2721

@aradng

Description

@aradng

Describe the bug
in an attemp to replicate this:

re-declaring a dead queue does not create it with x-expires and binding fails (queue not found)
if i remove the x-expire everything works fine. just number of idle queues keep growing

How to reproduce
minimal code:

import asyncio

from faststream.rabbit import RabbitBroker
from faststream.rabbit.schemas import RabbitQueue, RabbitExchange
from faststream.rabbit.schemas.queue import ClassicQueueArgs


async def main():
    broker = RabbitBroker("amqp://guest:guest@localhost:5672/")

    exchange = RabbitExchange(
        name="amq.topic",
        type="topic",
        durable=True,
    )

    routing_key = "test.key"
    delay = 5  # seconds

    delay_queue = RabbitQueue(
        name=f"test.delay.{delay}",
        routing_key=f"{routing_key}.dlx.{delay}",
        durable=True,
        arguments=ClassicQueueArgs(
            {
                "x-dead-letter-exchange": exchange.name,
                "x-dead-letter-routing-key": routing_key,
                "x-message-ttl": delay * 1000,
                "x-expires": delay * 1000,
            }
        ),
    )

    final_queue = RabbitQueue(
        name="test.final",
        routing_key=routing_key,
        durable=True,
    )

    async with broker:
        await broker.declare_exchange(exchange)

        dq = await broker.declare_queue(delay_queue)
        fq = await broker.declare_queue(final_queue)

        await dq.bind(exchange, routing_key=f"{routing_key}.dlx.{delay}")
        await fq.bind(exchange, routing_key=routing_key)

        # publish message → should land in delay queue first,
        # then be dead-lettered to final queue after TTL
        await broker.publish(
            message={"hello": "world"},
            exchange=exchange.name,
            routing_key=f"{routing_key}.dlx.{delay}",
        )


if __name__ == "__main__":
    asyncio.run(main())

steps to reproduce the behavior:

  1. create a queue with x-expires to some value (we have this failing on 10 x delay in prod so grace period is not the issue)
  2. bind the queue to an exchange
  3. publish to queue
  4. wait for queue to die
  5. immediately re-declare, bind and publish
  6. cannot find queue on bind time

Expected behavior
the dlx queue get recreated and bound to parent exchange

Observed behavior
aiormq.exceptions.ChannelNotFoundEntity: NOT_FOUND - no queue {name}.{delay} in vhost

Environment

  • faststeram = 0.6.4
  • aio-pika >=9,<10
  • anyio >=4.0,<5
  • fast-depends >=3.0.0

Additional context
im not sure but might be related to this:
https://www.rabbitmq.com/docs/queues#shared-temporary-queues

Metadata

Metadata

Assignees

No one assigned

    Labels

    RabbitMQIssues related to `faststream.rabbit` module and RabbitMQ broker featuresbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions