HiveMQ Migration

Reconfigure MQTT Clients After HiveMQ: ESP32, Python, Node.js and Node-RED Examples

Every client that leaves HiveMQ Cloud Serverless needs a new hostname, credentials, client ID and TLS settings. Here are before-and-after examples for ESP32 (Arduino), Python, Node.js, Node-RED and mosquitto clients, plus the mistakes that cause failed connections.

Code editor showing MQTT client connection settings changing from a HiveMQ Cloud hostname to broker.connectmq.com for ESP32, Python and Node.js
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

Moving a client off HiveMQ Cloud Serverless changes four things: the hostname, the credentials, the client ID and sometimes the TLS trust settings. Your topics, payloads and application logic stay the same. This article shows exactly what to change for the most common clients, with before-and-after examples using a ConnectMQ private broker as the destination.

The broader process is in the HiveMQ Serverless migration guide.

What Changes and What Stays

Setting HiveMQ Cloud Serverless ConnectMQ
Hostname <cluster-id>.s1.eu.hivemq.cloud broker.connectmq.com
MQTT over TLS 8883 8883
Secure WebSocket 8884, path /mqtt 8084, path /mqtt
Username and password Created in the HiveMQ console Generated per broker in the ConnectMQ portal
Client ID Freely chosen The issued client ID, optionally with a _suffix
Root certificate Publicly trusted Let's Encrypt (ISRG Root X1), publicly trusted
Topics, payloads, QoS Unchanged Unchanged

Note the secure WebSocket port: browser dashboards often hard-code 8884, while ConnectMQ uses 8084. Check your HiveMQ console for the exact values your cluster used.

ESP32 With Arduino and PubSubClient

Before (HiveMQ Cloud):

const char* MQTT_HOST = "abc123.s1.eu.hivemq.cloud";
const char* MQTT_USER = "hivemq-user";
const char* MQTT_PASS = "hivemq-pass";
String clientId = "sensor-" + WiFi.macAddress();

After (ConnectMQ):

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

const char* MQTT_HOST = "broker.connectmq.com";
const int   MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_USERNAME";
const char* MQTT_PASS = "YOUR_PASSWORD";
const char* CLIENT_ID_BASE = "YOUR_CLIENT_ID";

// ISRG Root X1 (Let's Encrypt), paste the PEM from letsencrypt.org/certificates
static const char ROOT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
...ISRG Root X1...
-----END CERTIFICATE-----
)EOF";

WiFiClientSecure net;
PubSubClient mqtt(net);

void connectMqtt() {
  String mac = WiFi.macAddress();
  mac.replace(":", "");
  String clientId = String(CLIENT_ID_BASE) + "_" + mac;   // issued ID + unique suffix
  while (!mqtt.connected()) {
    if (mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
      mqtt.publish("site1/esp32/status", "online", true);  // republish retained state
      mqtt.subscribe("site1/esp32/cmd");
    } else {
      delay(5000);
    }
  }
}

void setup() {
  // ... connect Wi-Fi first ...
  net.setCACert(ROOT_CA);
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setBufferSize(1024);
  connectMqtt();
}

void loop() {
  if (!mqtt.connected()) connectMqtt();
  mqtt.loop();
}

If your HiveMQ firmware used setInsecure(), take this opportunity to verify certificates properly. More detail is in ESP32 MQTT over SSL. Remember the ESP32 needs the correct time for some TLS stacks; sync NTP before connecting.

Python With paho-mqtt 2.x

Before:

client.username_pw_set("hivemq-user", "hivemq-pass")
client.connect("abc123.s1.eu.hivemq.cloud", 8883)

After:

# pip install "paho-mqtt>=2.0"
import os, ssl
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe("site1/#", qos=1)

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=os.environ["MQTT_CLIENT_ID"] + "_ingest",
                     protocol=mqtt.MQTTv5)
client.username_pw_set(os.environ["MQTT_USERNAME"], os.environ["MQTT_PASSWORD"])
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)   # system CA store trusts Let's Encrypt
client.on_connect = on_connect
client.on_message = lambda c, u, m: print(m.topic, m.payload.decode())
client.connect("broker.connectmq.com", 8883)
client.loop_forever()

Subscribing in on_connect matters: it restores subscriptions after every reconnect, so the client never depends on session state stored by a broker. See paho-mqtt Python and paho-mqtt reconnect.

Node.js With MQTT.js

// npm install mqtt
const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  // was: mqtts://abc123.s1.eu.hivemq.cloud:8883
  username: process.env.MQTT_USERNAME,
  password: process.env.MQTT_PASSWORD,
  clientId: `${process.env.MQTT_CLIENT_ID}_api`,
  protocolVersion: 5,
  reconnectPeriod: 2000,
});

client.on("connect", () => client.subscribe("site1/+/telemetry", { qos: 1 }));
client.on("message", (topic, payload) => console.log(topic, payload.toString()));
client.on("error", (err) => console.error("MQTT error:", err.message));

For a browser dashboard, use wss://broker.connectmq.com:8084/mqtt with the same options. See MQTT.js with Node.js and MQTT over WebSocket.

Node-RED

In Node-RED, all MQTT nodes share one broker configuration node, so a migration is usually a single edit:

  1. Open any mqtt in or mqtt out node and click the pencil next to the server.
  2. Connection tab: set Server to broker.connectmq.com, Port to 8883, tick Use TLS and select a TLS configuration that verifies the server certificate. Set Protocol to MQTT V5 if you use MQTT 5 features.
  3. Client ID: enter your issued client ID with a suffix, for example YOUR_CLIENT_ID_nodered.
  4. Security tab: enter the new username and password.
  5. Deploy and check that the nodes show connected.

If the node keeps showing "connecting", see Node-RED MQTT not connecting and Node-RED MQTT TLS.

mosquitto Command-Line Clients

mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_CLIENT_ID_cli \
  -t 'site1/#' -v

On Windows or macOS, use --cafile with a PEM bundle that contains ISRG Root X1 instead of --capath.

Troubleshooting Failed Connections

Symptom Likely cause Fix
Not authorized / bad username or password Old HiveMQ credentials still in use Copy the new credentials from the portal
Connection refused right after CONNECT Client ID not matching the issued ID or _suffix pattern Use YOUR_CLIENT_ID or YOUR_CLIENT_ID_<suffix>
Two devices keep disconnecting each other Same client ID on both Derive a unique suffix from MAC or serial number
TLS handshake failure Device trust store lacks ISRG Root X1, or clock is wrong Add the root certificate, sync time. See MQTT TLS handshake failed
Browser cannot connect Wrong WebSocket port or path Use wss://broker.connectmq.com:8084/mqtt
Connect works, publishes rejected QoS 2 or payload above plan limit Use QoS 1 on Serverless (Free), keep payloads under 256 KB, or upgrade
Reason code 0x97 Plan connection quota exceeded Upgrade the plan before the next wave

Make the Next Change Easier

While you are editing every client anyway, move the hostname, port, credentials and client ID into configuration that can be updated remotely: a config file, environment variables, a provisioning service or an OTA settings payload. Then rotating credentials or changing brokers in the future is a configuration push, not a firmware project.

You can test any of these examples right now against a free broker at app.connectmq.com.

Frequently Asked Questions

Do I need to change my topics when leaving HiveMQ Cloud?

No. Topics, payloads and QoS levels stay the same. Only the connection settings change.

Why does ConnectMQ require a specific client ID?

Binding client IDs to credentials prevents another tenant or a leaked credential from impersonating your devices. You can still run many clients per credential set by appending a unique suffix.

Is port 8883 the same on both brokers?

Yes, MQTT over TLS uses 8883 on both. The secure WebSocket port differs: ConnectMQ uses 8084 with the path /mqtt.

Can I keep using setInsecure on the ESP32?

It will connect, but it skips server verification and exposes devices to impersonation. Use the ISRG Root X1 certificate instead.

Related articles

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.