KubeMQ
ConnectorsRabbitMQ (AMQP 0-9-1)Concepts

Exchanges and Routing

How RabbitMQ exchange types (direct, fanout, topic, headers) work as virtual connector-side routing, resolved at publish time into KubeMQ Queue channels.

In the KubeMQ RabbitMQ connector, exchanges and bindings are virtual connector-side routing metadata, not data stores. There is no exchange object holding messages — a publish to an exchange is resolved into a set of target queues at publish time, and each resolved queue is written to its KubeMQ Queue channel amqp.{vhost}.{queue}. This guide covers the exchange types, topic wildcards, declare idempotency, and what happens to the routing result.

Every AMQP queue maps to a single KubeMQ Queue channel amqp.{vhost}.{queue}. Exchanges and bindings exist only to select which queues a publish lands in — they are evaluated by the connector at publish time, then discarded. See Architecture.

How a publish routes

The matcher produces a set of target queues, deduplicates it, runs a per-queue authorization check, and then writes the message to each surviving queue's KubeMQ channel.

Exchange types

Exchange typeRouting semanticsPre-declared (per vhost)
default ("")Implicit per-queue binding; routing-key = queue name; a missing queue is unroutableimplicit
directExact routing-key match; multiple bindings on the same key all matchamq.direct (durable)
fanoutAll bound queues; routing key ignoredamq.fanout (durable)
topicTrie matcher; * = exactly one word, # = zero or more words, . = word separatoramq.topic (durable)
headersx-matchany-with-x (default all); x--prefixed headers are excluded from matchingamq.headers / amq.match (durable)

Pre-declared amq.* exchanges

The amq.direct, amq.fanout, amq.topic, amq.headers, and amq.match exchanges are pre-declared durable per vhost. They:

  • cannot be deleted by a client → 403 access-refused;
  • cannot be redeclared with different args406 precondition-failed;
  • a client declaring any exchange with an amq.* prefix → 403.

Topic wildcards

The topic matcher uses . as the word separator:

TokenMatches
*exactly one word
#zero or more words

Worked examples:

Binding patternMatchesDoes NOT match
stock.*.nysestock.ibm.nysestock.ibm.us.nyse (two words for *)
stock.#stock, stock.a, stock.a.bstocks.a
#any key, including the empty key
*.orange.*quick.orange.rabbitlazy.orange.elephant.x

Bindings and declare idempotency

  • Declare idempotency: identical args → ok; any field mismatch (type / durable / auto-delete / internal / deep-equal arguments) → 406.
  • Passive declare (passive=true): exists → ok; missing → 404 not-found.

The routing result

  1. The exchange matcher produces a set of target queues.
  2. The set is deduplicated — a message matching multiple bindings to the same queue is delivered exactly once.
  3. A per-queue Casbin Write check runs; denied queues are silently removed + amqp.publish.denied audit — see Authentication.
  4. If the routed set is empty:
    • mandatory=truebasic.return(312 NO_ROUTE) with the full message content;
    • otherwise the message is silently dropped.

See Reliability for mandatory / basic.return.

Unsupported / inert routing features

FeatureBehavior
Exchange-to-exchange bindings (exchange.bind / exchange.unbind)540 not-implemented (capability advertised false).
alternate-exchange argumentAccepted and stored, but inert — WARN once; badged in the dashboard.

Inert arguments. Several exchange/queue arguments are accepted (and badged in the dashboard topology view) but never alter behavior: alternate-exchange, priority queues, x-max-length / overflow, x-queue-type / mode, single-active-consumer, x-expires, and consumer x-priority. Don't rely on them. See Capabilities.

Error quick reference

TriggerCode
Unmatched direct routing key, no mandatorysilent drop
mandatory=true and unroutable312
Redeclare with mismatched args406
Passive declare of a missing exchange404
Client declares an amq.* exchange / deletes a pre-declared exchange403
exchange.bind / exchange.unbind540

Was this page helpful?

On this page