# 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:** 3

<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 16:06 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/41 "2026-07-06T16:06:58Z")

</div>

Cool - would be great to get a 2nd set of eyes on it. Once I push a branch, I can provide instructions for running from source (if you need them)

---

<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 16:37 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/42 "2026-07-06T16:37:17Z")

</div>

> [@Steve-Mcl](#):
>
> Once I push a branch, I can provide instructions for running from source (if you need them)

Will that be a node-red build? I haven't done that, but I think it is documented somewhere so can probably work it out with a small amount of guidance.

---

<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:** [7 July 2026 11:50 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/43 "2026-07-07T11:50:40Z")

</div>

I see from the HiveMQ videos that MQTT v5 offers other new features that could be valuable to Node-red, eg shared subscriptions, enhanced authentication, user properties.

Will this new node support these features too? No idea how much coding beyond extra config options would be needed!

---

<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:** [7 July 2026 12:03 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/44 "2026-07-07T12:03:05Z")

</div>

Yes. But not introduced here - the mqtt in and out nodes already support all of these v5 features (I added those a few years back).

---

<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:** [9 July 2026 06:44 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/45 "2026-07-09T06:44:50Z")

</div>

> [@Colin](#):
>
> > [@Steve-Mcl](#):
> >
> > Once I push a branch, I can provide instructions for running from source (if you need them)
> 
> Will that be a node-red build?

Kinda.

The PR is raised here: [feat: MQTT Request Node - official v5 request-response support by Steve-Mcl · Pull Request #5860 · node-red/node-red · GitHub](https://github.com/node-red/node-red/pull/5860)

### Minimal instructions (assumes linux)

Will install node-red source in `~/src/node-red`  
_change as required_

```bash
mkdir ~/src
cd ~/src
git clone git@github.com:node-red/node-red.git
cd node-red
git switch feat-mqtt-request
npm ci
npm run dev

```

_If you already have a node-red instance running locally, you can start with parameters like this: `npm run dev -- --userDir "~/.node-red-1881" --port 1881`_

---

<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:** [10 July 2026 10:08 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/46 "2026-07-10T10:08:46Z")

</div>

Well it appears to be working 🙂

Now I shall try and break it. 😈

---

<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:** [10 July 2026 12:41 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/47 "2026-07-10T12:41:27Z")

</div>

A bit of an anomaly:

1. Configure the node to connect to a broker on a different machine, where one can pull the ethernet cable from the node red machine (or otherwise break the connection). Leave timeout at 5 seconds
2. Add Catch and Complete nodes
3. Build the response flow on the remote machine
4. Test it works, obviously.
5. Pull the cable
6. Before the node shows disconnected (which is about a minute on my system) post a couple of requests
7. The messages passed in, but not sent, do not generate timeout errors in the Catch node
8. Wait for the node to show Disconnected and plug the cable back in
9. When the node connects again then valid responses are emitted, even though the timeout is long gone.

---

<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:** [10 July 2026 13:17 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/48 "2026-07-10T13:17:46Z")

</div>

Good stuff.

I suspect that is the client doing its job and delivering the initial request on reconnection.

The timeout doesnt start until a successful subscribe so that slow subscription comms doesnt eat up the timeout

I think it is an acceptable behaviour TBH.

A future option like "✅ start timeout after subscription" which can be disabled for the behaviour you are describing is a possibility.

Happy to discuss further.

---

<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:** [10 July 2026 14:02 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/49 "2026-07-10T14:02:03Z")

</div>

> [@Steve-Mcl](#):
>
> The timeout doesnt start until a successful subscribe so that slow subscription comms doesnt eat up the timeout

Do you mean successful publish? Is it not permanently subscribed?  
I don't understand the logic, if you have slow comms then you can increase the timeout.

In my use case (guaranteed delivery of messages) I send one message at a time and wait for Complete or Timeout. If it Completes then I send the next one, if it times out then I wait a bit and try again. However, I need to impose a 'super timeout' in the flow that forces a retry if I don't see any response from the node after some time. That is to prevent lockup due to a lost message such as can occur in a partial deploy for example. So I need to know that if I wait long enough then I can be sure that the message is lost. With the current code it seems there is no way of knowing for certain that the message is not going to suddenly generate a Complete message hours later when the network recovers

I don't see what advantage there is in waiting before starting the timeout. Certainly it is not what I expected.

---

<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:** [11 July 2026 15:02 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/50 "2026-07-11T15:02:36Z")

</div>

Apart from the timeout it is working well, for my guaranteed delivery flow, in the sender it has enabled me to reduce

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/2/b/2bcdd5c9a335516c95f82c4c6dd45d18b8eb13e4.png)

To this

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/8/58351ba8d79dd832caf9ce9339466c1fdab9780b.png)

I do need the timeout to work from when the message is posted however. Otherwise I think I will have to put back several of the nodes in my original flow, provide my own correlation data, and check each message as it comes back to make sure it is from the most recent message.

---

<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:** [12 July 2026 08:10 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/51 "2026-07-12T08:10:23Z")

</div>

> [@Colin](#):
>
> Do you mean successful publish

That depends on the qos (qos 0 is fire and forget)

> [@Colin](#):
>
> Is it not permanently subscribed

Yes, if it's a static response topic. No if it is passed in the msg (dynamic response topic).

If you do get an error during subscription, it will throw a catchable error.

There is a grey area tho - in a half open connection state (like you describe) - the (existing) behaviour of the mqtt client we use is that if you manage to catch it, the message gets queued by the internal store. Upon connect it's delivered. This is shared behaviour across the mqtt nodes and changing that will change existing behaviours.

I do add a v5 message expiry value to the packet but that is (strictly speaking) a broker implementation so late delivery may or may not be rejected depending on the broker. (Not sure how mqtt.js handles these, but to be clear, the behaviour is broker specific not client specific)

Another caveat is if I DO start the timeout BEFORE subscription & it is delayed/slow subscribing (such that the message reaches the client but the node times out before the response arrives) is that you won't know (or rather think it failed) so a non idempotent receiver action would be triggered again when you do a resend.

  

All that said, you do make some valid points and so I have updated the MQTT Request PR to do the following:

_before reading the bullets, I have (hopefully) made this clear in the built-in help - the points below are in case i didnt do a good job of that 😉_

- **The timeout now runs end-to-end** - it starts the moment the message arrives and covers the whole exchange (subscribe → publish → waiting for the reply). So you always get one outcome within the timeout: either a response on the output, or an error, even if the connection is half-open and the subscribe/publish stalls.

- **On timeout, the error tells you what actually happened.** The (catchable) error message distinguishes _"delivered but no response"_ from _"not confirmed delivered"_, and the outgoing msg carries a small flag object:

- **If it gives up on a QoS 1/2 request that was never acknowledged, it is now purged from the client's outgoing store** so that it isn't silently retransmitted on reconnect. i.e. the "queued by the internal store, delivered on connect" behaviour you flagged. It will only do this while it's still unacknowledged; once it's been acked there's nothing to purge and so leave the store alone. The v5 message-expiry value is still set as the broker-side backstop

- **The original message is passed through** to the output (and to a Catch node on error) with its non-MQTT properties intact, so it slots into existing flows (http-in `req`/`res`, link-call, etc.) without losing context.

What this means to your guaranteed-delivery flows: just wait for the node to emit. Success → send the next one. Error → check `msg.mqtt.delivered`: `false` = safe to resend, `true` = it reached the broker so treat a resend as potentially duplicate. Either way you get a definite answer inside the timeout window, so no lock-up and no need for the external "super timeout".

* * *

Please `git pull` the changes, restart node-red (`npm run dev`) and test it out:

---

<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:** [12 July 2026 08:38 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/52 "2026-07-12T08:38:55Z")

</div>

Great, now working perfectly.

> [@Steve-Mcl](#):
>
> Another caveat is if I DO start the timeout BEFORE subscription & it is delayed/slow subscribing (such that the message reaches the client but the node times out before the response arrives) is that you won't know (or rather think it failed) so a non idempotent receiver action would be triggered again when you do a resend.

Yes, it has always been the case that the receiver may receive repeated requests, I don't think there is any way to avoid that. If it is important to the client that repeated requests are ignored then he would have to add a serial number, or similar, to allow detection of this.

---

<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:** [12 July 2026 09:09 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/53 "2026-07-12T09:09:37Z")

</div>

Good stuff.

Regarding that caveat, I have somewhat mitigated it for QoS 1 and QoS 2 (see the bit about " **If it gives up on a QoS 1/2 request that was never acknowledged, it is now purged from the client's outgoing store**" & the new flag `msg.mqtt.delivered` can help a user flow make informed decisions)

This is a difference in behaviour for the new node ONLY. It makes sense because this is about Request - Response specifically.

* * *

Please continue do to test and evaluate & let me know if there is any issues or subtleties to address before it becomes mainstream (assuming it is accepted of course)

---

<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:** [13 July 2026 08:28 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/54 "2026-07-13T08:28:22Z")

</div>

Yes, I am continuing to test. Dynamic topics seem to be working ok.

Having made yourself familiar again with the MQTT node, is there a chance that you could look at this existing issue? It would be useful to me, and I suspect it would be a simple change.

> <https://github.com/node-red/node-red/issues/5435>
>
> \### Current Behavior
> 
> Using an MQTT Out node, if any MQTT 5 user properties are …specified in the node then it should still be possible to add new properties using msg.userProperties. Currently this is not possible.
> 
> See #5360 for discussion as to whether this should be allowed. The conclusion was yes.
> 
> \### Expected Behavior
> 
> \_No response\_
> 
> \### Steps To Reproduce
> 
> \_No response\_
> 
> \### Example flow
> 
> \`\`\`
> paste your flow here
> \`\`\`
> 
> 
> \### Environment
> 
> \- Node-RED version:
> \- Node.js version:
> \- npm version:
> \- Platform/OS:
> \- Browser:

---

<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:** [13 July 2026 10:11 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/55 "2026-07-13T10:11:42Z")

</div>

Which has prompted me to consider whether the request node should allow configuration of user properties and content type.

---

<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:** [13 July 2026 10:59 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/56 "2026-07-13T10:59:44Z")

</div>

In this first iteration I deliberately left those off. However, you can send user properties, content type, etc, in the message.

---

<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:** [13 July 2026 11:23 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/57 "2026-07-13T11:23:40Z")

</div>

True, but is there any reason for it to be different in this respect from the MQTT Out node?

---

<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:** [13 July 2026 12:33 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/58 "2026-07-13T12:33:09Z")

</div>

Only implementation time. If the need for all bells and whistles is raised in review as a blocker, then the PR will either sit and wait for the extra work to get done or worse, it doesnt get done and doesnt get merged. As a first implementation, this is fairly feature complete (as a request response node) and there is nothing stopping tasks being raised for later follow up.

---

<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:** [13 July 2026 12:42 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/59 "2026-07-13T12:42:59Z")

</div>

Understood.

---

<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:** [13 July 2026 13:18 UTC](https://discourse.nodered.org/t/we-have-http-request-tcp-request-serial-request-any-objections-to-an-mqtt-request/101413/60 "2026-07-13T13:18:07Z")

</div>

OK, I have given it a pretty good going over and all seems to be well.

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

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