Addressing
The AMQP 1.0 terminus address grammar — pattern/channel prefixes, channel validation, longest-prefix matching, and dynamic and anonymous nodes.
The terminus address is the single most client-load-bearing fact about the KubeMQ AMQP 1.0
connector: it tells the connector which KubeMQ pattern and channel a link talks to. This
guide is the practical playbook for the <pattern>/<channel> grammar — always use explicit
prefixes — plus channel validation, longest-prefix matching, dynamic and anonymous addresses,
and the absence of vhosts.
For the address validation rules in table form, see Address mapping.
Where the address goes
AMQP 1.0 has no exchanges or routing keys. You choose the destination by setting a terminus address on the link — and where it goes depends on the link role:
| You are… | The address goes in… |
|---|---|
| a receiver (you consume) | the link source address |
| a sender to a fixed node (you produce) | the link target address |
| an anonymous sender | properties.to on each message (the target is null) |
The grammar — always use explicit prefixes
address := [ "/" ] pattern "/" channel # leading "/" is optional: queues/x ≡ /queues/x
| bare # no recognized prefix → JMS hint, else DefaultPattern
| "/responses/" RequestID # RPC reply token (reply path only; server-receiver only)
| <dynamic> # source.dynamic / target.dynamic → _amqp10.tmp.<connID>.<uuid>
pattern := "queues" | "events" | "events-store" | "commands" | "queries"| Terminus address | KubeMQ pattern | Channel |
|---|---|---|
queues/<ch> | queues | <ch> |
events/<ch> | events | <ch> |
events-store/<ch> | events-store | <ch> |
commands/<ch> | commands | <ch> |
queries/<ch> | queries | <ch> |
responses/<RequestID> | responses (synthetic; RPC reply path only) | the opaque reply token |
bare (no prefix, no /) | JMS node-capability hint (queue→queues, topic→events), else DefaultPattern | the bare string |
| null target on a sender | anonymous — routed per-message by properties.to | (per message) |
anything else containing / | error → DETACH(amqp:not-found, "unknown address prefix") | — |
The leading slash is optional and stripped: queues/orders ≡ /queues/orders. The prefix is
stripped, never prepended — the resolved channel (orders) is what the broker sees, so it
always passes the underlying channel validation.
Always emit the explicit <pattern>/<channel> prefix. It makes the destination
deterministic and self-documenting: queues/orders, events/telemetry,
events-store/audit, commands/provision, queries/lookup. Do not rely on bare addressing
in fresh application code (see below).
Longest-prefix matching
The connector matches prefixes longest-first: events-store/ is tested before
events/. So events-store/audit resolves to the events-store pattern with channel
audit — it is never mis-read as the events pattern with channel store/audit. You never
need to escape or disambiguate; just write the full prefix. The full matching order is
events-store → queues → events → commands → queries → responses.
Bare addressing — a Qpid-JMS migration convenience only
A bare address (no recognized prefix and no /) is resolved non-deterministically:
- If the terminus carries a JMS node-capability hint, it selects the pattern:
queue→ queues,topic→ events. - Otherwise the connector's configured
DefaultPatternapplies (defaultqueues).
This exists so a migrating Qpid-JMS / ActiveMQ app can point at KubeMQ by changing only the
connection string and the destination name — a JMS Queue("orders") carries the queue
capability and lands on queues/orders without an explicit prefix.
Bare addressing is non-deterministic and config-dependent: the same bare name resolves
differently depending on the client's capability hint and the broker's DefaultPattern. Treat
it as a migration aid, not a design choice. For any fresh code, use the explicit prefix so
the destination is unambiguous and survives a DefaultPattern change. A bare value that still
contains a / is treated as an unknown prefix, not a bare channel →
DETACH(amqp:not-found, "unknown address prefix").
Channel validation — stricter than the native layer
After the prefix is stripped, the connector validates the channel more strictly than the
underlying KubeMQ array layer. A channel that works on the gRPC/native side can be rejected
over AMQP. A violation closes the link with DETACH(amqp:not-found):
| Rejected channel | Example |
|---|---|
| empty | queues/ |
| longer than 255 characters | queues/<256+ chars> |
has a trailing . | queues/orders. |
| contains whitespace | queues/my orders |
contains * or > wildcards | queues/orders.* |
contains ; or : | queues/a:b, queues/a;b |
A channel name that works on the native KubeMQ side can be rejected over AMQP because of
the extra ;, :, and trailing-. restrictions. Keep AMQP channel names to [a-zA-Z0-9._-],
≤ 255 chars, with no trailing dot, and you are never surprised.
Dynamic and anonymous addresses
These are special address forms the connector mints or routes specially.
Dynamic nodes (source.dynamic / target.dynamic)
Attach a receiver with DynamicAddress: true (a dynamic source) and the connector creates a
fresh node and echoes its address in the reply ATTACH: _amqp10.tmp.<connID>.<uuid>. This is
the mechanism for an RPC reply node — a requester opens a dynamic receiver, reads back its
echoed address, and stamps it as reply-to. See
Commands.
Dynamic nodes are node-local: a temp node created on node A is not reachable from node B. RPC replies are still cluster-safe (they travel the broker reply path), but a direct cross-node send to a dynamic address is not.
Anonymous terminus (null target sender)
A sender opened with a null target (NewSender("", nil)) is an anonymous sender: it has no
fixed destination, and each message selects its destination via properties.to (which itself
uses the <pattern>/<channel> grammar). Because there is no fixed channel at attach,
authorization is deferred to a per-message Write check on each message's to (see
Authentication). A bad to →
amqp:precondition-failed; a missing to → a Send error.
The connector advertises no ANONYMOUS-RELAY capability — anonymous-terminus routing works
by the connector inspecting properties.to, not by a capability handshake. Clients whose
anonymous-producer API depends on ANONYMOUS-RELAY negotiation (notably Qpid JMS) cannot
emit the single null-target link the connector routes on, so they cannot drive the anonymous
terminus — use explicit per-pattern senders there instead.
/responses/ reply tokens
/responses/<RequestID> is a synthetic RPC reply address. It is valid only as a
server-receiver attach (the reply path); a receiver attach on /responses/ →
DETACH(amqp:not-allowed). You do not construct these yourself in normal use — the RPC layer
manages them, and they are connection-scoped (not authorized via Casbin).
No vhost
AMQP 1.0 has no vhost. The OPEN hostname field (which a client carrying over a 0-9-1
mental model might set) is logged then ignored. There is no vhost option to expose and no
namespace scoping by hostname.
Reaching AMQP 0-9-1 data
The AMQP 1.0 and AMQP 0-9-1 connectors do not share a namespace. AMQP 0-9-1 queues live on
KubeMQ channels named amqp.<vhost>.<queue>. To reach the same data from an AMQP 1.0 client,
use the explicit queues prefix over that channel name:
/queues/amqp.<vhost>.<queue>Cross-protocol equivalence holds the other way too: an AMQP 1.0 queues/<ch> maps to the bare
KubeMQ channel <ch>, so a gRPC/native client producing to <ch> interoperates with an AMQP
1.0 consumer of queues/<ch>.
Quick reference
| Destination | Address to use |
|---|---|
Queue orders | queues/orders |
Event stream telemetry | events/telemetry |
Durable event stream audit | events-store/audit |
Command channel provision | commands/provision |
Query channel lookup | queries/lookup |
| RPC reply node | dynamic receiver (DynamicAddress: true); never a hand-built address |
| Route per-message | anonymous sender + properties.to = "queues/<ch>" etc. |
| AMQP 0-9-1 queue | /queues/amqp.<vhost>.<queue> |
| Fresh app code | always the explicit prefix — never rely on bare addressing |
Related
Address mapping
The full grammar, channel-validation, and the Qpid-JMS anonymous-terminus limitation as reference tables.
Authentication
SASL identity and the per-message Write check on an anonymous sender's properties.to.
Commands
How dynamic reply nodes and the /responses/ token drive request/reply over AMQP 1.0.
Was this page helpful?
AMQP 1.0
Point an AMQP 1.0 app at KubeMQ by changing only the connection string and node address — all five KubeMQ patterns over the OASIS AMQP 1.0 wire.
Architecture
Inside the AMQP 1.0 connector — the amqpmux shared front door, the connection/session/link model, address-to-pattern mapping, and the metadata envelope.