Node-RED

Node-RED MQTT TLS: Configuring the Broker Node Securely

Configure Node-RED's mqtt-broker node for an encrypted connection on port 8883, with certificate verification, credentials, MQTT 5 options and an importable flow, plus fixes for the errors you are most likely to see.

Node-RED MQTT TLS illustration with a Node-RED flow connecting to an MQTT broker through an encrypted padlocked link on port 8883
Run this on your own MQTT brokerGet a private, managed MQTT broker on the Free plan and start from ready-made code samples.
Try it free Code samples No card required

Node-RED MQTT TLS configuration takes a few minutes, but a couple of easily missed fields decide whether your connection is truly secure or just encrypted. This tutorial configures the mqtt-broker config node for port 8883 with certificate verification, credentials and MQTT 5, gives you an importable flow, and explains the errors you might see along the way.

How TLS Works in Node-RED

Node-RED's MQTT nodes are built on MQTT.js and Node.js's TLS stack. Three pieces are involved:

  • mqtt-broker config node: holds the server, port, client ID, protocol version, credentials and a "Use TLS" checkbox.
  • tls-config node: a separate config node that holds TLS options such as CA certificate, client certificate, server name and whether to verify the server certificate.
  • mqtt in / mqtt out nodes: reference the broker node; they do not have TLS settings of their own.

When the broker uses a certificate from a publicly trusted CA, Node.js already trusts it through its bundled Mozilla root list. The ConnectMQ broker uses a Let's Encrypt certificate, so you do not need to upload any CA file; you only need to enable TLS and keep verification on.

If Node-RED is not installed yet, follow our guide to install Node-RED first.

Port and Protocol Choices

Option Server field Port When to use
MQTT over TLS broker.connectmq.com 8883 Default for Node-RED on servers, PCs and gateways
Secure WebSocket wss://broker.connectmq.com:8084/mqtt 8084 Networks that block 8883 but allow HTTPS-style traffic
Plain MQTT broker.connectmq.com 1883 Local testing on the public broker only

Step-by-Step Node-RED MQTT TLS Configuration

Step 1: Create the Broker Node

Drag an mqtt in node onto the workspace and double-click it. Next to Server, choose Add new mqtt-broker and click the pencil icon.

On the Connection tab:

  1. Server: broker.connectmq.com
  2. Port: 8883
  3. Connect automatically: checked
  4. Use TLS: checked
  5. Protocol: MQTT V5 (or V3.1.1 if your other clients need it)
  6. Client ID: the client ID generated in the broker portal (YOUR_CLIENT_ID). Never leave it empty for a private broker, and never reuse it in another client, or the two connections will keep disconnecting each other.
  7. Keep Alive: 60 seconds is a sensible default.

Step 2: Add the TLS Configuration

When you tick Use TLS, a TLS Configuration field appears. Choose Add new tls-config and click the pencil icon:

  • Certificate / Private Key: leave empty. These are for client certificate (mutual TLS) authentication, which ConnectMQ does not use; it authenticates with username and password over TLS.
  • CA Certificate: leave empty for publicly trusted brokers. Upload your CA file only for a private broker with its own CA.
  • Verify server certificate: checked. This is the most important box on the page.
  • Server Name: broker.connectmq.com. Node.js normally derives SNI from the server field, but setting it explicitly avoids surprises.
  • Name: a descriptive label such as Cloud broker TLS, so you can reuse the node in other broker configurations.

Click Add to return to the broker node.

Step 3: Enter Credentials

On the broker node's Security tab, enter the Username and Password from the portal. Node-RED stores these in flows_cred.json, separate from the flow, and they are never included when you export flows. Set credentialSecret in settings.js so this file is encrypted with a key you control rather than an auto-generated one; otherwise moving the project to another machine can leave you with unreadable credentials.

Step 4: Optional MQTT 5 Settings

With MQTT V5 selected, extra options appear:

  • Session Expiry on the broker node: how long the broker keeps your subscriptions and queued QoS 1/2 messages after a disconnect. Combined with a fixed client ID and clean start off, this lets a restarted Node-RED instance pick up messages it missed.
  • Messages tab: birth, close and will messages. A retained birth message such as {"status":"online"} and a will message {"status":"offline"} on a status topic give you a simple health indicator.
  • mqtt in options: retain handling, "no local" (do not receive your own publications) and "retain as published".
  • mqtt out options: message expiry, content type, response topic, correlation data and user properties.

Our overview of MQTT 5 features explains each of these in more detail.

Step 5: Deploy and Verify

Point the mqtt in node at a topic such as factory/line1/#, wire it to a debug node and click Deploy. Within a few seconds the node status should change to a green "connected". If it shows "connecting" indefinitely or "disconnected", jump to the troubleshooting section below.

Importable Example Flow

Import this flow (menu, Import, paste) to get a complete TLS setup in one step. It uses the public MQTT test broker over TLS with anonymous access, so it works immediately. Replace 8b2f with your own random characters; for a private broker, change the client ID and add credentials on the Security tab.

[
  {
    "id": "f1e2d3c4b5a69701",
    "type": "tls-config",
    "name": "ConnectMQ TLS",
    "cert": "",
    "key": "",
    "ca": "",
    "certname": "",
    "keyname": "",
    "caname": "",
    "servername": "broker.connectmq.com",
    "verifyservercert": true,
    "alpnprotocol": ""
  },
  {
    "id": "f1e2d3c4b5a69702",
    "type": "mqtt-broker",
    "name": "ConnectMQ over TLS",
    "broker": "broker.connectmq.com",
    "port": "8883",
    "tls": "f1e2d3c4b5a69701",
    "clientid": "nodered-tls-8b2f",
    "autoConnect": true,
    "usetls": true,
    "protocolVersion": "5",
    "keepalive": "60",
    "cleansession": true,
    "autoUnsubscribe": true,
    "sessionExpiry": "",
    "birthTopic": "connectmq/demo/8b2f/nodered/status",
    "birthQos": "1",
    "birthRetain": "true",
    "birthPayload": "{\"status\":\"online\"}",
    "willTopic": "connectmq/demo/8b2f/nodered/status",
    "willQos": "1",
    "willRetain": "true",
    "willPayload": "{\"status\":\"offline\"}"
  },
  {
    "id": "f1e2d3c4b5a69703",
    "type": "inject",
    "name": "Every 10 s",
    "props": [{ "p": "payload" }],
    "repeat": "10",
    "once": true,
    "onceDelay": "2",
    "topic": "",
    "payload": "",
    "payloadType": "date",
    "x": 140,
    "y": 80,
    "wires": [["f1e2d3c4b5a69704"]]
  },
  {
    "id": "f1e2d3c4b5a69704",
    "type": "change",
    "name": "Build reading",
    "rules": [
      { "t": "set", "p": "payload", "pt": "msg", "to": "{\"ts\": payload, \"value\": $round($random() * 100, 1)}", "tot": "jsonata" },
      { "t": "set", "p": "topic", "pt": "msg", "to": "connectmq/demo/8b2f/nodered/reading", "tot": "str" }
    ],
    "x": 330,
    "y": 80,
    "wires": [["f1e2d3c4b5a69705"]]
  },
  {
    "id": "f1e2d3c4b5a69705",
    "type": "mqtt out",
    "name": "Publish over TLS",
    "topic": "",
    "qos": "1",
    "retain": "false",
    "broker": "f1e2d3c4b5a69702",
    "x": 540,
    "y": 80,
    "wires": []
  },
  {
    "id": "f1e2d3c4b5a69706",
    "type": "mqtt in",
    "name": "Subscribe over TLS",
    "topic": "connectmq/demo/8b2f/nodered/#",
    "qos": "1",
    "datatype": "auto-detect",
    "broker": "f1e2d3c4b5a69702",
    "nl": false,
    "rap": true,
    "rh": 0,
    "inputs": 0,
    "x": 160,
    "y": 160,
    "wires": [["f1e2d3c4b5a69707"]]
  },
  {
    "id": "f1e2d3c4b5a69707",
    "type": "debug",
    "name": "Show",
    "active": true,
    "tosidebar": true,
    "console": false,
    "complete": "true",
    "targetType": "full",
    "x": 370,
    "y": 160,
    "wires": []
  }
]

After deploying, the debug sidebar shows the retained "online" status and a new reading every ten seconds, all travelling over TLS. The public area is visible to everyone, so use it only for test data.

Using Secure WebSocket Instead

If your network blocks port 8883, put a full URL in the Server field: wss://broker.connectmq.com:8084/mqtt. Node-RED then ignores the port field and connects over secure WebSocket on 8084, with TLS handled by the same certificate verification. This is common on corporate networks; see MQTT over WebSocket for background.

Troubleshooting Node-RED MQTT TLS

  1. Stuck on "connecting": port 8883 is probably blocked. Test from the Node-RED host with openssl s_client -connect broker.connectmq.com:8883 -servername broker.connectmq.com and try WSS on 8084.
  2. "unable to get local issuer certificate" in the log: Node.js cannot build the chain. Usually caused by TLS inspection on the network, or by an uploaded CA file that replaced the defaults with the wrong root. Remove the CA file for publicly trusted brokers.
  3. "Hostname/IP does not match certificate's altnames": you entered an IP address or alias. Use the hostname.
  4. "Connection refused: Not authorized" or a reason code after connecting: TLS works; the credentials or client ID are wrong. Re-copy them from the portal.
  5. Connects, then disconnects every few seconds: another client uses the same client ID, often a second Node-RED instance or a forgotten test script.
  6. "Use TLS" unticked while the port is 8883: the connection hangs or drops because the broker expects a TLS handshake on 8883, so "Use TLS" must be ticked.

The Node-RED MQTT not connecting guide and fixing MQTT TLS handshake failures cover more cases. Never untick Verify server certificate to make an error disappear; that hides the real cause and removes protection against impostor brokers.

Hardening the Rest of Your Node-RED Setup

An encrypted broker connection is one layer. Also protect the editor with adminAuth, serve it over HTTPS, keep Node-RED and its nodes updated, and set credentialSecret. Our guide to secure Node-RED covers each step, and the Node-RED MQTT tutorial shows how to structure topics and payloads for larger flows.

Run Your Node-RED Flows on ConnectMQ

Node-RED is an MQTT client, so it needs a reliable broker on the other end. A fully managed MQTT service like ConnectMQ gives you TLS on 8883, secure WebSocket on 8084, an automatically renewed certificate, and a portal with a live topic explorer and dashboard to check what your flows publish. Sign up at app.connectmq.com, choose the free Serverless plan with no credit card, create a broker and paste the generated username, password and client ID into the broker node. To compare hosting models first, read our cloud MQTT broker guide.

Frequently Asked Questions

Do I need to upload a CA certificate in Node-RED for ConnectMQ?

No. Its certificate is issued by Let's Encrypt, which Node.js already trusts. Enable TLS, keep "Verify server certificate" checked and leave the CA field empty.

Are my MQTT credentials included when I export a flow?

No. Node-RED stores credentials separately in flows_cred.json and excludes them from exports, so you must re-enter them after importing on another instance.

Can several Node-RED instances share one broker configuration?

They can share the same settings, but each instance needs its own unique client ID. Two clients with the same ID will keep disconnecting each other.

Should I choose MQTT V5 or V3.1.1 in the broker node?

Choose V5 unless another part of your system requires 3.1.1. V5 adds session expiry, message expiry, user properties and clearer reason codes, and ConnectMQ supports both versions.

Related articles

Node-RED OPC UA Client to MQTT with ISA-95 Topics

Use node-red-contrib-opcua to subscribe to OPC UA variables on a PLC or simulation server, map node IDs to ISA-95 style MQTT topics, and publish values with quality and timestamps.

9 min read

All articles →

Your private MQTT broker is a few clicks away

Create an account, get your broker credentials and connect your first device — no servers to install, patch or scale.