MQTT Request and Response: Bound Correlation-Data Lifetimes Across Late Replies

Use MQTT 5 Correlation Data as an application-owned binary token, not as a reused Packet Identifier or an index into a mutable request array. Associate that token with one pending request, an expected Response Topic, a deadline and a requester generation. A late reply must fail that ownership check instead of completing a newer operation that happens to occupy the same slot.

This guide pins the OASIS MQTT 5.0 Standard, 7 March 2019, sections 3.3.2.3.5, 3.3.2.3.6 and 4.10. It covers response association and resource lifetime. Command expiry, execution deduplication and business transaction recovery are outside scope. An original serialized pending-request model was executed; no broker or responder was contacted.

Keep routing and correlation separate

Response Topic is a UTF-8 string used as the response publication’s Topic Name and cannot contain wildcards. Its presence identifies the original application message as a request. Correlation Data is Binary Data whose interpretation belongs to the requesting and responding applications.

The broker forwards both properties unchanged to subscribers receiving the request, and forwards response Correlation Data as part of normal message routing. It does not maintain an RPC promise that one responder will answer one requester exactly once.

Both properties are single-instance properties: including either one more than once is a protocol error. Keep that wire-validation rule separate from the application question of whether the returned correlation token is currently owned.

Request A has binary token generation1 sequence1 and expires. Request B receives generation1 sequence2, so A's late response cannot match it. After requester restart a generation2 token also differs. A response completes only a matching pending token on its expected topic before the deadline.
The generation travels inside Correlation Data. Unlike a local-only counter, it can distinguish an old reply when the responder echoes it.

Subscribe before sending a request

The standard’s non-normative request/response pattern normally has the requester subscribe to its Response Topic before publishing. Use the client’s supported SUBACK result to establish readiness for the intended filter, rather than assuming a queued subscribe call already guarantees response delivery.

Choose a Response Topic that the requester is authorized to subscribe to and the responder is authorized to publish to. A requester-specific topic simplifies ownership, but its naming scheme must fit the deployment’s authorization policy.

Response Information in CONNACK is an optional hint mechanism. MQTT does not define its string contents, and it does not automatically create or subscribe a response topic. Treat any interpretation as an application or broker-specific contract.

Define the pending-entry contract

Field Purpose
Exact correlation bytes and length Match the response without text conversion
Requester generation and sequence Prevent reuse across new requests and restarts
Expected response topic Reject unrelated routing paths
Monotonic deadline Bound the response association lifetime
Request schema and completion policy Validate the response and decide how many answers are expected
Terminal state Prevent duplicate completion or timer races

Allocate and publish this entry before a fast responder can reply. Copy the correlation bytes into storage owned for the required lifetime; do not retain a pointer to a temporary packet buffer after its receive callback ends.

Correlation Data can contain zero bytes. Using strlen, treating it as UTF-8 or comparing only a printable prefix can collapse distinct tokens. The executed fixture used an eight-byte token containing zero bytes and compared it as an exact byte sequence.

Put the generation on the wire

A local table generation alone cannot distinguish two identical tokens received on the same response route. Include an application generation in the token itself, or use another uniqueness mechanism with a documented collision and reuse policy.

The hypothetical fixture uses four bytes of generation followed by four bytes of sequence. That layout is an example, not a recommended universal capacity. A production design must prevent wrap or generation reuse while old responses can still exist, including across restart and restored backups.

The responder’s application contract echoes the request’s correlation bytes. MQTT’s explanatory request/response pattern describes this behavior, but the broker does not force arbitrary responder code to implement it. Qualify the actual responder and report missing or changed correlation as a protocol-integration failure.

Make terminal ownership a single decision

The receive path validates topic, token, response schema and deadline before transferring the pending entry to a terminal state. The timeout path competes for the same transition. Use one serialized owner or correct synchronization so only one path completes the application operation.

After completion or timeout, remove the entry from the active table. A late or duplicate reply then has no active owner and is discarded or counted in bounded diagnostics. “Quarantine” need not mean keeping every unsolicited payload in an unbounded buffer.

A full table should reject or defer new requests rather than reusing an active token. Keep request admission and deadline processing functional when responders are slow or absent.

An executed late-reply trace

Request A uses generation one, sequence one and expires at synthetic time ten. The model removes A, then allocates B with sequence two. A’s late reply is rejected while B remains pending. A response on the wrong topic also leaves B pending.

A correct response completes B once; its duplicate cannot complete anything again. A new requester generation rejects the old token, and a response arriving exactly at the model’s deadline follows its explicitly chosen expired policy.

The fixture also rejected allocation beyond a one-entry capacity. These assertions exercise serialized application ownership. They do not prove thread safety, durable generation allocation, responder behavior or network delivery.

Account for responder multiplicity and trust

There can be zero, one or multiple responders subscribed to the request topic, and multiple subscribers to the Response Topic. If the product expects one answer, document which accepted answer ends the request and how later answers are treated. A collect-many operation needs a different bounded completion policy.

The standard’s example response omits Response Topic, avoiding creation of another request in that pattern. Retained response behavior also needs deliberate application policy so a newly subscribed requester does not mistake historical data for a fresh answer.

Correlation is not authentication. A matching token does not establish that a trusted responder produced the payload. Enforce the deployment’s topic authorization and message-authenticity requirements separately, without putting secrets into correlation logs.

Acceptance evidence

Run fast-response-before-submit-return, late response, duplicate response, wrong topic, missing correlation, new requester generation and capacity-exhaustion tests. Verify the chosen single or multiple-responder policy with the real application.

The final contract should explain who owns each pending response and exactly when that ownership ends. A timeout ends the requester’s wait; it does not prove that a remote command failed to execute or authorize its replay.

Similar Posts