Articles · October 17, 2026
Connect an ESP32 to a free MQTT broker over TLS
This guide gets an ESP32 publishing sensor readings and receiving commands over encrypted MQTT, using the Arduino framework, the PubSubClient library and a free broker from mqtty. It takes about ten minutes.
What you need
- An ESP32 board and the Arduino IDE or PlatformIO with the ESP32 core installed.
- The PubSubClient library by Nick O'Leary (Library Manager).
- A free mqtty account: sign in at broker.mqtty.com and create a credential. Note the username and password; the password is shown only once.
Why TLS, and which certificate
Port 8883 is MQTT over TLS: your Wi-Fi password and readings stay encrypted between the board and the broker. The ESP32 needs to trust the broker's certificate authority. mqtty uses Let's Encrypt and, on its MQTT ports, serves a chain that validates against ISRG Root X1. Download it from letsencrypt.org/certs/isrgrootx1.pem and paste it into the sketch. It is valid until 2035, so you won't need to reflash for years.
The sketch
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASS = "your-wifi-password";
const char* MQTT_HOST = "broker.mqtty.com";
const char* MQTT_USER = "mq-xxxxxxxxxx"; // from the mqtty dashboard
const char* MQTT_PASS = "your-mqtty-password";
// ISRG Root X1: paste https://letsencrypt.org/certs/isrgrootx1.pem here
const char* ROOT_CA = R"PEM(
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
)PEM";
WiFiClientSecure net;
PubSubClient mqtt(net);
unsigned long lastSend = 0;
void onMessage(char* topic, byte* payload, unsigned int len) {
Serial.printf("%s: %.*s\n", topic, len, (char*)payload);
}
void connectMqtt() {
while (!mqtt.connected()) {
Serial.print("Connecting to MQTT... ");
if (mqtt.connect("esp32-kitchen", MQTT_USER, MQTT_PASS)) {
Serial.println("ok");
mqtt.subscribe("home/kitchen/led");
} else {
Serial.printf("failed, state %d\n", mqtt.state());
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
net.setCACert(ROOT_CA);
mqtt.setServer(MQTT_HOST, 8883);
mqtt.setCallback(onMessage);
}
void loop() {
connectMqtt();
mqtt.loop();
if (millis() - lastSend > 10000) { // every 10 s = 6 messages a minute
lastSend = millis();
float t = temperatureRead(); // replace with your sensor
mqtt.publish("home/kitchen/temp", String(t, 1).c_str());
}
}Upload it and open the serial monitor at 115200 baud. Within a few seconds you should see Connecting to MQTT... ok, and the device appears under Connected devices in your mqtty dashboard, with each reading in the live message feed marked ▲.
Send it a command
From the dashboard or any MQTT client, publish on to home/kitchen/led. The ESP32 prints it, and the dashboard shows the delivery to the device marked ▼. From a computer with Mosquitto installed:
mosquitto_pub -h broker.mqtty.com -p 8883 --capath /etc/ssl/certs \ -u YOUR_USER -P YOUR_PASS -t home/kitchen/led -m on
Common errors
mqtt.state() | Meaning | Fix |
|---|---|---|
| -2 | Network connect failed | Usually TLS: check the root certificate and port 8883 |
| 4 or 5 | Bad credentials or not authorized | Copy the username and password again (case sensitive), and check the credential still exists in the dashboard |
| 3 | Server unavailable | All 6 device slots are in use; disconnect one |
Two more tips. Give every board its own client ID: two devices with the same ID keep kicking each other off. And stay under the free plan's 30 messages per minute per account. One reading every 10 seconds from three boards is 18 a minute, plenty of headroom.
Next steps
Point Home Assistant or Node-RED at the same broker, subscribe to home/#, and you have a complete setup with no server to maintain. Every message is kept for 60 days, so you can always check what your sensors did. Get your free broker at mqtty.
mqtty gives every account 6 devices, 30 messages per minute and 60 days of history, with TLS and a live dashboard.
Start free with mqtty →