# We have http-request, tcp-request, serial-request - any objections to an mqtt-request?

**URL:** https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413
**Category:** Feature Requests
**Created:** [5 July 2026 19:45 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413 "2026-07-05T19:45:39Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [5 July 2026 19:45 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/1 "2026-07-05T19:45:39Z")

</div>

MQTT v5 added first-class **request/response** support (Response Topic + Correlation Data properties), but today doing an MQTT request in Node-RED means hand-rolling it: publish on one topic, subscribe on another, generate and track correlation IDs, keep a map of in-flight requests keyed by correlation data, handle timeouts, and clean it all up. It works (I have done it several times), but it's a lot of function-node plumbing for something that should be simple!

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/7/379520216b58c104f3b1cc2eeda9f70785a6508a.png)

_ **Before / after** (screenshot): the top flow is the DIY version - a lookup map keyed by correlation data, timeout monitoring, cleanup, and an `mqttReply` helper stashed in flow context. The bottom flow is the same thing with a single **`mqtt request`** node._

### What it does

- Publishes your `msg` as the request, then resolves with the correlated response as a single output message (or throws an errors on timeout).
- Pure MQTT v5 request/response uses sets `responseTopic` + `correlationData` on the outbound publish and matches the reply by correlation data.
- Reuses the existing **mqtt-broker** config node.

### Behaviour / decisions I'd like feedback on

- The MQTT Request nodes output message `topic` is swapped back so that the request `topic` stays in `topic` and original response topic is set to `msg.requestTopic`. This might sound normal, but the first time I implemented this, naturally, the response message arrives with its own `msg.topic` (set to the published response topic) - i felt this was odd and swapped them!
- **Response topic** : The node recommends (and defaults to) a _static_ topic string field since subscribe is done once and shared accross the broker. Optionally, it can be set via ENV VAR in the `typedinput` so that `compound/${MY_VAR}/topics` can be used. Additionally, it does support _dynamic_ (`msg.`) subscribe per-request and tear down after the reply/timeout. Reasonable?
- **Correlation data** : The default is set to auto-generate a UUID. Alternatively it can be provided in the message via a property - a tip warning is shown about collisions
- **QoS** : defaults to **1** (not 0) since a dropped response would only surface as a timeout; **2 is not the default** because it isn't universally supported (e.g. AWS IoT). Agree?
- **Message expiry** : outbound request's `messageExpiryInterval` is tied to the timeout, so a stale request isn't acted on after we've given up. This is defaulted to a number `5` but can be set by ENV and can be sent in by a `msg` property
- **v5-only** : the node hard-depends on v5. Currently: if the selected broker isn't v5 it disables itself, shows a warning status + edit-panel tip, and rejects input. Right call, or should it degrade some other way?

### Notes

- I will fight requests to change the topic to a plain text input (like current MQTT nodes)
  - Why? Because I love using the $ ENV typed input for things like `{SITE_ID}/{DEPT_ID}/{SERVER_ID}/status`

- I deliberately excluded `jsonata`/`flow`/`global` on the `topic`, `responseTopic` & `correlationData` fields. It just adds complexity! For now, it is simple and we can always use a change node if the current options are not enough. I might consider adding extra options in a follow up iteration (or accept a PR for that)

### Editor Screenshots:

![chrome_X833aIyGRu](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/4/f4bf1531164d93413b991df153a469a8e913afc3.gif)

Any objections, prior work I've missed on the forum / PR, or any edge cases (shared response topics across nodes, correlation-data collisions, broker quirks) I should think about before I throw a PR together (and invest time in unit tests)?

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [5 July 2026 21:14 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/2 "2026-07-05T21:14:22Z")

</div>

> [@Steve-Mcl](#):
>
> - I love using the $ ENV typed input for things like `{SITE_ID}/{DEPT_ID}/{SERVER_ID}/status`

Can you do that ? I thought the env syntax only allowed a single variable name - not compositions ? when did that change ?

Do you need to worry about possible queue depths at all while waiting for (non)responses ?

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [5 July 2026 21:30 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/3 "2026-07-05T21:30:16Z")

</div>

> [@dceejay](#):
>
> Can you do that ? I thought the env syntax only allowed a single variable name - not compositions

It definitely works for a a single composite replacement but you now have me doubting multiples.

From [the help:](https://nodered.org/docs/user-guide/environment-variables#using-the-typedinput-widget)

> if ${} is present, it will substitute the corresponding environment variable into the result: For example, given the value "Hello ${FOO}" and the env var FOO is set to World, this results in the value "Hello World"

If memory serves, I've definitely done multiples! Dang brain not braining

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [5 July 2026 21:34 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/4 "2026-07-05T21:34:47Z")

</div>

> [@dceejay](#):
>
> Do you need to worry about possible queue depths at all while waiting for (non)responses

It occurred to me during development then I completely forgot to look in to it. Any pointers to give me a head start (a code link, a variable name, even a current node that does this) @dceejay

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [5 July 2026 21:38 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/5 "2026-07-05T21:38:46Z")

</div>

It came up recently (which is why I remembered) over here - [Help with `delay` node set to `rate limit` - #16 by dceejay](https://discourse.nodered.org/t/help-with-delay-node-set-to-rate-limit/101400/16)

---

<div class="post-metadata">

### Author: ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)
#### Post date: [5 July 2026 22:13 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/6 "2026-07-05T22:13:24Z")

</div>

Will you be able to detect the circumstance where the broker (Mosquitto) supports MQTT V5 but the remote server (eg Tasmota) does not?

---

<div class="post-metadata">

### Author: ![krambriw](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/krambriw/32/5429_2.png) [@krambriw](https://discourse.nodered.org/u/krambriw)
#### Post date: [6 July 2026 06:20 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/7 "2026-07-06T06:20:38Z")

</div>

What is the use case for such feature? Just wondering why polling should be needed...

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 July 2026 06:27 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/8 "2026-07-06T06:27:33Z")

</div>

Is the idea to add another core node or to do this with a separate `mqttv5-request-response` node package? Can't you create such a node package and leave it at that? Why and what is the reasoning to add a core node for this?

The fewer core nodes, the less the chance that something breaks in core and the less needs to be maintained in core.

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 07:23 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/9 "2026-07-06T07:23:34Z")

</div>

Hey @jbudd I dont use Tasmota but I did look into this for you.

At this time, unless Tasmota upgrades to an MQTT v5 lib, not at this time. There is an [open issue here](https://github.com/arendst/Tasmota/discussions/17969) but no one has suggested an alternative lib. A quick search reveals more than one candidate e.g. [mqtt5nano](https://docs.arduino.cc/libraries/mqtt5nano/), [ESP32\_MQTTv5](https://www.arduinolibraries.info/libraries/esp32_mqt-tv5), [H4AsyncMQTT](https://github.com/HamzaHajeir/H4AsyncMQTT) - maybe if you add these suggestions they will get traction?

* * *

Alternative solution - if the MQTT Request node were to be permitted on V3 brokers, we would have to provide a way to embed the necessary v5 properties in the `payload` itself e.g.

```json
payload: {
  "value": "your payload embeded in an object to allow other properties",
   "_properties": {
      "correlationData": "<correl>",
      "responseTopic": "<restop>",
   }
}

```

From there, you would setup a Berry Script. Berry allows you to subscribe to arbitrary MQTT topics, parse JSON payloads, execute local commands, and publish the results back dynamically.

* * *

v3 support could be a future iteration if there is enough interest - but not likely to land in first iteration

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 07:42 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/10 "2026-07-06T07:42:18Z")

</div>

> [@krambriw](#):
>
> What is the use case for such feature?

In a distributed system where data or operations live on separate edge devices, matching asynchronous responses back to the original triggering flow is incredibly clunky in MQTT v3.1.1.

A classic use case is **on-demand commanding**. Imagine a dashboard button or an API call that needs to query a specific device for a value, read a single database row from a remote server, or trigger a camera snapshot _right now_. Instead of subscribing to a continuous stream of data you don't need, you fire a single request and get the immediate answer back in line within the exact same flow. Couple that with multiple users performing operations at the some time and it gets complex very quickly

Here are some articles that do a better job of explaining than me:

- [MQTT Request-Response Pattern – MQTT 5 Essentials Part 9](https://www.hivemq.com/blog/mqtt5-essentials-part9-request-response-pattern/)
- [MQTT 5 Request Response Pattern Explained: RPC Over MQTT](https://scadaprotocols.com/mqtt-5-request-response/)
- [MQTT Request / Response Explained and Example | MQTT 5 Features | EMQ](https://www.emqx.com/en/blog/mqtt5-request-response)

> [@krambriw](#):
>
> Just wondering why polling should be needed

What polling? This is 100% asynchronous and event-driven.

I see why you might think that if you imagine someone poorly implementing a loop to constantly poll a resource, but that isn't the purpose of an MQTT Request node. It standardises the request response pattern. Before v5, every engineering team invented their own workaround (like cramming IDs into JSON payloads). There was no protocol-level enforcement, leading to broken interoperability between different vendor systems.

Let me just finish with this: _once you know you need this - you need it bad_ 😃

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 08:04 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/11 "2026-07-06T08:04:36Z")

</div>

> [@gregorius](#):
>
> Is the idea to add another core node or to do this with a separate `mqttv5-request-response` node package?

Core node. It shares deep functionality with the existing MQTT core codebase, and I want it to be a first-class citizen.

> [@gregorius](#):
>
> Can't you create such a node package and leave it at that?

Not cleanly. Doing this as an external package would require duplicating a large amount of the core code. It would lead to code divergence, maintenance fragmentation, and inevitably falling behind core updates.

To me, it doesn’t make sense to have native v5 MQTT support in Node-RED core while omitting one of the defining features of the v5 specification. Adding support for this pattern has been on my radar since I first introduced MQTT v5 to Node-RED core a few years ago. Recently, I’ve been integrating external systems where I had to handle this manually - it was cumbersome and clunky, which is exactly why a native solution is being proposed.

> [@gregorius](#):
>
> The fewer core nodes, the less the chance that something breaks in core and the less needs to be maintained in core.

I totally appreciate that concern, and as a rule of thumb, it’s a valid point. However, in this case, an MQTT Request node conceptually belongs in core right alongside `http request` and `tcp request`, alongside its brother and sister `mqtt in` and `mqtt out` nodes.

FWIW there are no new code files being added/required in core (only modification to the network/mqtt\* files). There are no new external dependencies or entirely new code subsystems being introduced. They use no additional runtime resources if you dont use them and minimal when you do. It is deliberately a separate node from the MQTT IN and MQTT OUT (so no breakage to existing nodes) and a clean dedicated design (for purpose) in both naming and feature (atomic).

Providing 1st class support for a foundational protocol pattern like this belongs in Node-RED core (IMHO)

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [6 July 2026 08:11 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/12 "2026-07-06T08:11:56Z")

</div>

> [@Steve-Mcl](#):
>
> _once you know you need this - you need it bad_ 😃

... in over 20 years of using MQTT I have never knowingly needed it 🙂 ... if I ever wanted something like that (before Node-RED) I would ensure the topic was a retained one, then just subscribe to the topic - data would be delivered - then unsubscribe - but again, that was incredibly rare.

If I really need to do single command response then things like http are "really useful" and well documented 🙂

But hey I can see it does complete a set of tools so by all means make it so.

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 08:22 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/13 "2026-07-06T08:22:38Z")

</div>

> [@dceejay](#):
>
> > [@Steve-Mcl](#):
> >
> > _once you know you need this - you need it bad_ 😃
> 
> ... in over 20 years of using MQTT I have never knowingly needed it 🙂 ... if I ever wanted something like that (before Node-RED) I would ensure the topic was a retained one, then just subscribe to the topic - data would be delivered - then unsubscribe - but again, that was incredibly rare.

Don't get me wrong, there are workarounds Dave (and I've used them!) - but having to build that custom logic on three different systems recently is what finally drove me to this.

The MQTT v3 approach of "retaining a topic, subscribing on the fly, and then unsubscribing" works fine for isolated or low-throughput tasks, but it does hit a wall - it gets incredibly tricky incredibly quickly when you layer on unknown/dynamic response topics, multitenant requirements, external system enforcements (to the v5 spec).

> [@dceejay](#):
>
> But hey I can see it does complete a set of tools so by all means make it so.

Muchas Grassy Bottom

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [6 July 2026 08:26 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/14 "2026-07-06T08:26:40Z")

</div>

Probably you have considered this already, but while implementing this, bear in mind the operation if the broker and/or the response client are across a network. They may go offline temporarily and so messages can be queued at various points and may eventually get dropped or may be delivered some time later when the network recovers. This can lead, for example, to repeated responses from the same request, or a response to arrive long after the initial request has timed out.

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 July 2026 08:27 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/15 "2026-07-06T08:27:57Z")

</div>

> [@Steve-Mcl](#):
>
> In a distributed system where data or operations live on separate edge devices, matching asynchronous responses back to the original triggering flow is incredibly clunky in MQTT v3.1.1.

A good example of feature-creep in MQTT. A message bus is, by design, asynchronous. Adding state (i.e. session) by coordinating request and response pairs is going beyond what a message bus should be doing - by design.

If I use a message bus, I don't expect it to be handling stateful request-response patterns. Strangely MQTT does do this. If I want request-response, then something like TCP/IP or HTTP would be more appropriate.

This is just a perspective of the MQTT specification, that it should be implemented if its available is clear. It's just unfortunate that such a feature made it into the specification.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [6 July 2026 08:33 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/16 "2026-07-06T08:33:38Z")

</div>

Another use case is where you need to absolutely guarantee that every message from a client gets delivered to the other client, even if the network connection can fail temporarily. Currently this is complex to achieve, an MQTT response node would make it significantly simpler.

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 08:34 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/17 "2026-07-06T08:34:28Z")

</div>

**`<OFF-TOPIC>`**

> [@Steve-Mcl](#):
>
> > [@dceejay](#):
> >
> > Can you do that ? I thought the env syntax only allowed a single variable name - not compositions
> 
> It definitely works for a a single composite replacement but you now have me doubting multiples.

@dceejay The brain fog cleared:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/8/4820fd48a141c7f4987be1baf7edfcf8a1754c66.png)

The ENV typed input does indeed permit multiple substitutions (I knew I wasnt dreaming 😉 )

**`</OFF-TOPIC>`**

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [6 July 2026 08:36 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/18 "2026-07-06T08:36:21Z")

</div>

> [@gregorius](#):
>
> If I want request-response, then something like TCP/IP or HTTP would be more appropriate.

If the connection is over a WAN then that would likely involve opening ports into the response client, which using MQTT avoids.

---

<div class="post-metadata">

### Author: ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)
#### Post date: [6 July 2026 09:13 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/19 "2026-07-06T09:13:17Z")

</div>

> [@Colin](#):
>
> which using MQTT avoids.

Ah ok, so MQTT handles the buffering of responses when networks drop away. Does the MQTT server than also handle the matching of requests/responses and send the client the appropriate pairing when it happens to have arrived?

I.e. so that the request-response pattern becomes transparent for the client.

From [here](https://www.hivemq.com/blog/mqtt5-essentials-part9-request-response-pattern):

> It’s important to note that this data is not relevant to the MQTT broker but serves to identify the relationship between sender and receiver.

So the client is still responsible for matching the original request with the response using the extra `correlationData` field in MQTTv5. So the client has to maintain the state while the broker remains stateless.

So then the new mqtt node here needs to know how to match request/response pairs using `correlationData` - I assume this would be a "simple" look up in a lookup table somewhere.

---

<div class="post-metadata">

### Author: ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)
#### Post date: [6 July 2026 09:15 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/20 "2026-07-06T09:15:56Z")

</div>

> [@dceejay](#):
>
> Do you need to worry about possible queue depths at all while waiting for (non)responses ?

> [@dceejay](#):
>
> came up recently (which is why I remembered) over here - [Help with `delay` node set to `rate limit` - #16 by dceejay](https://discourse.nodered.org/t/help-with-delay-node-set-to-rate-limit/101400/16)

Thanks Dave. That lead me straight to it - I updated code late last night but didnt get around to posting back that I added support for `nodeMessageBufferMaxLength` until now:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/1/31418bbce2e1d2919388ddb077a920ac91262509.png)

Much appreciated.

[Next page](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413.md?page=2)
