# Address Mapping (/connectors/amqp/reference/address-mapping)



This is the master reference for how the embedded KubeMQ AMQP 1.0 connector maps an
AMQP 1.0 terminus **address*&#x2A; to a KubeMQ &#x2A;*(pattern, channel)** pair — which server
link role results from a peer's source/target choice, and the channel-naming rules,
anonymous-routing behavior, and RPC reply token that each pattern carries.

<Callout type="info">
  **One rule above all — use the explicit prefix.** Always address a node with its full
  `<pattern>/<channel>` form (`queues/orders`, `events/telemetry`,
  `events-store/audit`). The bare-address / `DefaultPattern` fallback exists, but explicit
  prefixes are unambiguous and portable. See
  [Addressing](/connectors/amqp/concepts/addressing).
</Callout>

## Address grammar [#address-grammar]

```text
address       = [ "/" ] ( prefixed-node | bare-node )
prefixed-node = pattern-prefix channel
pattern-prefix = "queues/" | "events/" | "events-store/"
               | "commands/" | "queries/" | "responses/"
bare-node     = channel                 ; no "/" — resolved via node-cap hint or DefaultPattern
channel       = 1*255 VCHAR             ; connector charset rules (see Channel validation)
```

* The **leading slash is optional**. The resolver strips at most one leading `/` before
  matching, so `queues/orders` and `/queues/orders` resolve identically.
* Each pattern prefix **includes its trailing slash** (`"events/"`, `"events-store/"`),
  so the prefix match is unambiguous.
* A null/empty address is **not** an error in itself — on a server-receiver link it
  selects the **anonymous terminus** (see below); on a dynamic terminus it asks the
  server to **mint a node**.

## The master mapping table [#the-master-mapping-table]

The pattern is taken from the address prefix. The **server link role** is the inverse of
the peer's role: a peer **receiver** attaches against a **source** address (the server
*sends*), and a peer **sender** attaches against a **target** address (the server
*receives*).

| Pattern                         | Send to (peer → server, **target**)                      | Receive from (server → peer, **source**)       | Server link role                     | Settlement & credit                                                                                                                                                                                                                                                                            | Filters / link-props                                                                                                     |
| ------------------------------- | -------------------------------------------------------- | ---------------------------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Queues**                      | `queues/<channel>`                                       | `queues/<channel>`                             | produce = receiver; consume = sender | at-least-once (unsettled) **or** at-most-once (pre-settled `snd-settle-mode=settled` + `rcv-settle-mode=first`); consumer grants link credit; `accept`/`release`/`modify`/`reject&#x60; dispositions; &#x2A;*`copy` distribution-mode rejected → `amqp:invalid-field`** (queues are move-only) | **no** selector (selector on a queue → `amqp:not-implemented`); no link-props                                            |
| **Events**                      | `events/<channel>`                                       | `events/<channel>`                             | produce = receiver; consume = sender | at-most-once fan-out; **continuous credit required** — a transfer with 0 link credit is **silently dropped**                                                                                                                                                                                   | consume link may carry a **selector** (`apache.org:selector-filter:string`) and/or `x-opt-kubemq-group` (consumer group) |
| **Events Store**                | `events-store/<channel>`                                 | `events-store/<channel>`                       | produce = receiver; consume = sender | durable replay; durable identity from a **stable container-id + link name**; a second live attach of the same identity → `amqp:not-allowed`                                                                                                                                                    | consume link may carry a **selector*&#x2A;, &#x2A;*`x-opt-kubemq-start`** (start position), and `x-opt-kubemq-group`     |
| **Commands** (RPC)              | `commands/<channel>`                                     | — (requester reads its **dynamic reply node**) | request = receiver                   | native RPC; reply carries body + `x-opt-kubemq-executed` / `x-opt-kubemq-error`; failure → `executed=false` reply                                                                                                                                                                              | `reply-to` + `correlation-id` on the request message                                                                     |
| **Queries** (RPC)               | `queries/<channel>`                                      | — (requester reads its **dynamic reply node**) | request = receiver                   | native RPC; reply carries **body + metadata only** (no executed/error); failure → no reply (requester times out)                                                                                                                                                                               | `reply-to` + `correlation-id` on the request message                                                                     |
| **Responses** (RPC reply token) | `responses/<RequestID>` (peer **sender** writes a reply) | —                                              | receiver only                        | connection-scoped reply token; **write-only**                                                                                                                                                                                                                                                  | none                                                                                                                     |

Notes carried by the table:

* The same `<pattern>/<channel>` resolves to the **same KubeMQ channel** regardless of
  link direction — only the server role (and therefore the authorization check) differs.
* `commands/`, `queries/`, and `responses/` are RPC machinery. A requester's *reply* link
  is a **dynamic node**, not a `<pattern>/<channel>` address (see below).
* `responses/<RequestID>` is valid **only** as a server-receiver link (the peer is a
  sender writing the reply). A **receiver** attach against `responses/` is rejected with
  `amqp:not-allowed`.

## Longest-prefix discipline [#longest-prefix-discipline]

`events-store/` and `events/` share a common stem. The resolver matches `events-store/`
**before** `events/`, so `events-store/audit` is never mis-classified as the `events`
pattern with channel `store/audit`. The prefix checks run in this fixed order:

```text
events-store/   — checked FIRST
queues/
events/
commands/
queries/
responses/
```

A bare address that still contains a `/` but matches **no** recognized prefix is an
&#x2A;*unknown prefix → `amqp:not-found`** — a bare KubeMQ channel may use `.` segments but
never the reserved `/` separator.

## Special rows — bare, dynamic, anonymous, responses [#special-rows--bare-dynamic-anonymous-responses]

| Row                    | What the client does                                                                                      | How the connector resolves it                                                                                                                                                                                                                                                                                             |
| ---------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Bare address**       | attaches to a channel with no `pattern/` prefix (e.g. `orders`)                                           | a JMS **node-capability** hint on the terminus selects the pattern: `queue` → `queues`, `topic` → `events`; otherwise the configured `DefaultPattern` applies (degrading to `queues` if misconfigured)                                                                                                                    |
| **Dynamic terminus**   | attaches with `source.dynamic=true` (receiver) or `target.dynamic=true` (sender) and an **empty address** | the server mints a transient node `_amqp10.tmp.<connID>.<uuid>`, echoes it in the reply ATTACH, and backs it with an in-memory node-local mailbox; **no broker channel, no §2 resolution, no attach-time authz** (the node is connection-private by its unguessable address)                                              |
| **Anonymous terminus** | a **server-receiver** link with a **null target address**; routes per-message by `properties.to`          | the link binds to no fixed channel; each transfer's `to` is resolved with the **full mapping table** (including `responses/` tokens and dynamic nodes) and authorized **per message** for Write. A missing/invalid `to` or an unreachable node → `amqp:precondition-failed`; an authz denial → `amqp:unauthorized-access` |
| **Responses token**    | a peer **sender** writes a reply to `responses/<RequestID>`                                               | resolves to `(responses, RequestID)`; the RequestID is opaque (validated by the RPC layer against the pending-reply map, not as a broker channel — only emptiness is rejected). A **receiver** attach → `amqp:not-allowed`                                                                                                |

<Callout type="warn">
  **Anonymous terminus is null-target-driven, not capability-driven.** The connector
  advertises **no `ANONYMOUS-RELAY` capability** (see [Capabilities](/connectors/amqp/reference/capabilities)).
  A client gets anonymous routing by attaching a sender link with a **null target**, never
  by negotiating a capability. **Qpid JMS cannot drive the anonymous terminus** — it gates
  the single anonymous producer link on the peer's `ANONYMOUS-RELAY` capability, finds none,
  and falls back to per-destination sender links. Native clients
  (`Azure/go-amqp`, AMQPNetLite, qpid-proton, fe2o3-amqp, rhea) can open a null-target sender
  directly.
</Callout>

## Server role and authorization [#server-role-and-authorization]

The peer's link role and the chosen terminus side together fix the server role and the
permission required at attach:

| Peer attaches as                       | Terminus side read | Server role     | Permission enforced at attach                         |
| -------------------------------------- | ------------------ | --------------- | ----------------------------------------------------- |
| **receiver** (peer reads)              | `source`           | server-sender   | **Read** on `(pattern, channel)`                      |
| **sender** (peer writes), fixed target | `target`           | server-receiver | **Write** on `(pattern, channel)`                     |
| **sender**, null target (anonymous)    | —                  | server-receiver | deferred — **per-message Write** on the resolved `to` |
| **sender** to `responses/<id>`         | `target`           | server-receiver | **none** (connection-scoped reply token)              |

The pattern → authorization resource map treats `events-store` as the resource
`events_store`, and `commands` / `queries` as `commands` / `queries`. See
[Authentication](/connectors/amqp/how-to/authentication).

## Channel validation (connector charset) [#channel-validation-connector-charset]

The channel component (everything after the pattern prefix) is validated by a connector
charset rule that is **stricter*&#x2A; than the array-layer validation, so a channel that
passes here always passes downstream. Any violation maps to &#x2A;*`amqp:not-found`** (a bad
address is "not found"):

| Rule                   | Rejected example   | Reason                                        |
| ---------------------- | ------------------ | --------------------------------------------- |
| not empty              | `queues/`          | empty channel                                 |
| ≤ 255 bytes            | 300-char channel   | channel exceeds 255 chars                     |
| no trailing `.`        | `queues/orders.`   | channel has trailing `.`                      |
| no whitespace          | `queues/my orders` | channel contains whitespace (space/tab/CR/LF) |
| no `*` or `>` wildcard | `queues/orders.*`  | channel contains wildcard                     |
| no `;` or `:`          | `queues/a:b`       | channel contains `;` or `:`                   |

<Callout type="warn">
  **The channel charset is stricter than you may expect.** `*`, `>`, `;`, `:`, whitespace,
  and a trailing `.` are all rejected at attach with `amqp:not-found`. Use `.` only as a
  path separator inside the channel (e.g. `queues/region.eu.orders`).
</Callout>

There is **no vhost / virtual host**. The OPEN `hostname` field is accepted but ignored —
the address space is flat and global. For AMQP 0-9-1 interop the channel convention is
`queues/amqp.<vhost>.<queue>` (a naming convention, not a real vhost).

## Quick examples [#quick-examples]

| AMQP address, attached as         | Peer role | Resolves to                                  | Server role              |
| --------------------------------- | --------- | -------------------------------------------- | ------------------------ |
| `queues/orders`                   | sender    | `(queues, orders)`                           | receiver (Write)         |
| `queues/orders`                   | receiver  | `(queues, orders)`                           | sender (Read)            |
| `/events/telemetry`               | receiver  | `(events, telemetry)`                        | sender (Read)            |
| `events-store/audit`              | receiver  | `(events-store, audit)`                      | sender (Read)            |
| `commands/dispatch`               | sender    | `(commands, dispatch)`                       | receiver (Write)         |
| `responses/abc123`                | sender    | `(responses, abc123)`                        | receiver (no authz)      |
| `responses/abc123`                | receiver  | **DETACH** `amqp:not-allowed`                | —                        |
| `orders` (bare, node-cap `queue`) | sender    | `(queues, orders)`                           | receiver (Write)         |
| null target                       | sender    | anonymous terminus, routes by `to`           | receiver (per-msg Write) |
| `source.dynamic=true`, empty addr | receiver  | minted `_amqp10.tmp.<connID>.<uuid>`         | sender (no authz)        |
| `events/x;y`                      | receiver  | **DETACH** `amqp:not-found` (`;` in channel) | —                        |

## Related [#related]

<Cards>
  <Card title="Capabilities" href="/connectors/amqp/reference/capabilities" description="What the connector advertises, supports, and rejects — including the no-capabilities rule." />

  <Card title="Error Conditions" href="/connectors/amqp/reference/error-conditions" description="The 13 amqp:* symbolic conditions, their triggers, and client handling." />

  <Card title="Addressing" href="/connectors/amqp/concepts/addressing" description="Narrative guide to nodes, prefixes, and the channel charset." />

  <Card title="Authentication" href="/connectors/amqp/how-to/authentication" description="SASL PLAIN (JWT) / EXTERNAL (mTLS) and per-channel authorization." />
</Cards>
