KubeMQ
ConnectorsMQTTConcepts

Topic mapping

How the KubeMQ MQTT connector maps topics to patterns and channels — the prefix grammar, slash-to-dot, wildcards, $share consume, and $reply RPC replies.

The KubeMQ MQTT connector maps every MQTT topic to a KubeMQ messaging pattern and channel through a well-defined grammar. The first topic segment (the prefix) selects the KubeMQ pattern; the remaining segments become the channel name with / replaced by .. Understanding this grammar is essential before writing any producer or consumer code.

Prefix-to-pattern table

MQTT topicKubeMQ patternDirectionExample topicKubeMQ channel
events/<ch>Eventspublish + subscribeevents/site1/tempsite1.temp
store/<ch>Events-Storepublish + subscribe (StartNewOnly)store/site1/tempsite1.temp
queues/<ch>Queuespublish = produce onlyqueues/jobs/emailjobs.email
$share/<group>/queues/<ch>Queuessubscribe = consume (QoS ≥ 1)$share/g1/queues/jobs/emailjobs.email
commands/<ch>Commands (RPC)publish = send (MQTT 5.0 only)commands/svc/rebootsvc.reboot
queries/<ch>Queries (RPC)publish = send (MQTT 5.0 only)queries/svc/statussvc.status
$reply/<clientID>/<suffix>(broker-local)subscribe + RPC ResponseTopic$reply/c1/inboxnot routed to KubeMQ

Separator conversion: /.

MQTT uses / as the path separator; KubeMQ uses .. The connector converts every / in the channel portion of the topic to .:

events/site1/sensors/temp
       ↓ strip the prefix
       site1/sensors/temp
       ↓ replace / with .
       site1.sensors.temp        ← KubeMQ channel

This conversion is one-way on delivery: when the connector delivers a KubeMQ message to an MQTT subscriber, the channel's . separators are not converted back. The MQTT subscribe filter must match the dotted form.

A literal . in a topic segment is lossy. A . inside a segment maps to . in the channel — indistinguishable from a /-converted .. So events/a/b/c, events/a.b/c, and events/a/b.c all resolve to the same channel a.b.c. Use / exclusively for hierarchy in MQTT topics; reserve . for the channel names used on gRPC/REST clients.

Prefixless topics and DefaultPattern

A topic with no recognized prefix (e.g. sensor/data) is routed to the configured DefaultPattern:

DefaultPatternBehaviour
events (default)Routed to Events on channel sensor.data
storeRouted to Events-Store
nonePublish rejected — PUBACK 0x90; subscribe rejected — SUBACK 0x8F

Configure with CONNECTORSMQTT_DEFAULT_PATTERN (default events).

Wildcard subscriptions — Events only

MQTT wildcards are supported on Events subscriptions only. A wildcard subscribe on any other pattern is rejected with SUBACK 0xA2 (wildcard-subscriptions-not-supported).

MQTT wildcardKubeMQ equivalentExample filterMatches
+ (single level)*events/site1/+events/site1/temp, events/site1/hum
# (multi level)>events/site1/#events/site1/temp, events/site1/a/b/c

Rules:

  • # must be the final segment of the topic filter.
  • Both wildcards may appear in one filter: events/+/sensors/#.
  • A non-Events wildcard subscribe returns SUBACK 0xA2.

Overlapping wildcard filters deliver multiple copies. Each distinct Events subscribe filter creates an independent bridge entry, and there is no cross-entry deduplication. If a publish matches N of a client's overlapping filters (e.g. #, events/#, and the exact topic), the client receives N copies. Use non-overlapping filters when duplicate delivery is unacceptable.

Queue consume: $share shared subscriptions

A plain queue subscribe (queues/<ch>) is not allowed — it returns SUBACK 0x83. Queue consumption requires an MQTT 5.0 shared subscription:

$share/<group>/queues/<channel>
ComponentMeaning
$shareMQTT 5.0 shared-subscription prefix
<group>Group name — an audit/metrics label only (see the caveat below)
queues/<channel>Must resolve to the Queues pattern

QoS must be ≥ 1 — a QoS 0 shared-queue subscribe returns SUBACK 0x83.

The $share group name is audit/metrics-only. All groups compete in one shared KubeMQ queue pool — this is not MQTT per-group-copy semantics. $share/A/queues/x and $share/B/queues/x consume from the same pool (one copy total, any consumer wins), not one copy per group. For true fan-out to independent consumer groups, use different KubeMQ channels.

RPC reply topics: $reply/<clientID>/<suffix>

$reply is a broker-local reserved namespace for RPC response routing. It is never routed to KubeMQ — it stays inside the broker.

RuleDetails
Format$reply/<clientID>/<suffix>3 segments minimum
Own namespaceA client may only subscribe to / use as ResponseTopic its own $reply/<own-clientID>/...
Foreign namespaceUsing another client's $reply namespace → PUBACK 0x83 (publish with a foreign ResponseTopic)
RoutingNever forwarded to KubeMQ

An RPC client subscribes to its own reply topic before publishing the request, then sets it as Properties.ResponseTopic on the publish. See Commands and Queries for the full flow.

MQTT 5.0 User Properties ↔ KubeMQ Tags

On MQTT 5.0 connections, User Properties on a PUBLISH are carried into the KubeMQ message Tags, and vice versa on delivery. This mapping is 5.0 only — MQTT 3.1.1 has no User Properties field.

  • Inbound — every Properties.User entry on a 5.0 PUBLISH is copied 1:1 into the KubeMQ message Tags (duplicate keys are last-wins). Applies to Events, Events-Store, Queues publishes, and the RPC bridge.
  • Outbound — when a KubeMQ message is delivered to a 5.0 MQTT subscriber, its Tags are written back as Properties.User. A 3.1.1 subscriber receives no user properties.

Caps (per message):

CapLimitExceeded on 5.0Exceeded on 3.1.1
Max user-property count32PUBACK 0x97 + publish.errorSilent drop + publish.error
Max total bytes (all keys + values)4096PUBACK 0x97 + publish.errorSilent drop + publish.error

When either cap is exceeded the message is not routed.

Reason codes for invalid topics

TriggerPacketCode
DefaultPattern=none, prefixless publishPUBACK0x90 topic-name-invalid
DefaultPattern=none, prefixless subscribeSUBACK0x8F topic-filter-invalid
Empty channel segmentSUBACK0x8F topic-filter-invalid
Non-Events wildcard subscribeSUBACK0xA2 wildcard-subscriptions-not-supported
Plain queues/<ch> subscribeSUBACK0x83 implementation-specific
QoS 0 $share/*/queues/<ch> subscribeSUBACK0x83 implementation-specific
Foreign $reply namespace (publish)PUBACK0x83 implementation-specific

Was this page helpful?

On this page