MQTT: Message Queuing Telemetry Transport
A lightweight and very efficient messaging transport protocol based on TCP/IP protocol. More info can be found here
MQTT works with a broker (server) and one or more clients
It uses the pub/sub (publish/subscribe) mechanism: all clients can publish messages and can subscribe to one or more message
Installing MQTT on a Raspberry Pi:
sudo apt install mosquitto mosquitto-clients: this will install the broker as well as the clients on the Raspberry Pi and will also create and start the necessary service to start up the broker at start up of the RPi.
Once MQTT is installed on your device (Raspberry Pi, for instance) you can test out if the MQTT broker is working fine.
To do this, you have use the helper applications mosquitto_pub and mosquitto_sub. Both are installed automatically if you followed the installation command given in the section Installing MQTT.
Make sure the broker is running. Run the command ps aux | grep mosq
You should see something like this:
pi@domohome:~ $ ps aux | grep mosq
mosquit+ 445 0.0 0.4 8812 4612 ? Ss 10:07 0:01 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
pi 1379 0.0 0.0 7348 508 pts/4 S+ 10:41 0:00 grep --color=auto mosq
If you want to change the default values of the MQTT broker (e.g. change the default port address of 1883 for non-SSL connections) then change the configuration. However, this is not preferred according the documentation.
If you still want to modify things, do this by creating the file mosquitto.conf (as sudo!) in the directory /etc/mosquitto/conf.d and add - if you want to change the default port number, for instance - the following line to the newly created file:
port 1830
Make sure you have two command windows open, one for the subscriber and one for the publisher
In one command window, type the following command:
mosquitto_sub -v -t 'test/case'.
or
mosquitto_sub -v -p 1830 -t 'test/case' if you changed the default port number
This will:
start the subscription on the topic (option -t) 'test/case': the command will "hang" until it receives something from a publisher on the topic 'test/case')
show extra information since we passed the option -v (verbose)
In the other window type the following command:
mosquitto_pub -t 'test/case' -m 'MQTT broker is working!!!'
or
mosquitto_pub -p 1830 -t 'test/case' -m 'MQTT broker is working!!!' if you changed the default port number
This will:
publish a message -m 'MQTT broker is working!!!'
publish the message on the topic on the topic given -t 'test/case'
in case a specific port is given, the message will be sent to that specific port, here -p 1830
In both cases, you should see the message (-m parameter) appearing in the window where you started the subscription
Note that, when you add the option -v you will also see the topic next to the message in the MQTT subscriber output.
Note also that the -v option is only valid for the subscriber, not for the publisher!
Example without the -v option for the subscriber:
Subscription: mosquitto_sub -t 'test/case'
Publishing: mosquitto_pub -t 'test/case' -m "without -v option"
Result on the terminal where the MQTT subscriber runs: without -v option
Example with the -v option for the subscriber::
Subscription: mosquitto_sub -v -t 'test/case'
Publishing: mosquitto_pub -t 'test/case' -m "with -v option"
Result on the terminal where the MQTT subscriber runs: test/case with -v option
As you can see, the -v option also shows the topic on the subscriber side.
To know the MQTT version, run the command /usr/sbin/mosquitto -h. This will reveal the following information:
pi@domohome:~ $ /usr/sbin/mosquitto -h
mosquitto version 2.0.11
mosquitto is an MQTT v5.0/v3.1.1/v3.1 broker.
Usage: mosquitto [-c config_file] [-d] [-h] [-p port]
-c : specify the broker config file.
-d : put the broker into the background after starting.
-h : display this help.
-p : start the broker listening on the specified port.
Not recommended in conjunction with the -c option.
-v : verbose mode - enable all logging types. This overrides
any logging options given in the config file.
See https://mosquitto.org/ for more information.
The version used here is 3.1.1.
To make it possible to run mosquitto -h from everywhere, extend the path with /usr/sbin. You can add this to the extra bashrc file .bash_paths like so:
PATH=/usr/sbin:$PATH
When the file is picked up by the ~/.bashrc script (add it first) you will be able to run mosquitto -h from everywhere.
Install the complete MQTT suite on the Raspberry Pi, including libmosquitto-dev
sudo apt install mosquitto mosquitto-clients mosquitto-dev libmosquitto-dev
Create C application and include the mosquitto header file: #include <mosquitto.h>
Compile and link against mosquitto: gcc file.c -o file -lmosquitto
Example MQTT publishing application:
#include <stdio.h>
#include <mosquitto.h>
int main() {
int rc;
struct mosquitto * mosq;
mosquitto_lib_init();
mosq = mosquitto_new("publisher-test", true, NULL);
rc = mosquitto_connect(mosq, "localhost", 1066, 60);
if (rc != 0) {
printf("Client could not connect to broker! Error code: %d\n", rc);
mosquitto_destroy(mosq);
return -1;
}
printf("We are now connected to the broker!\n");
mosquitto_publish(mosq, NULL, "test/t1", 6, "Hello", 0, false);
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
For a full overview of the MQTT API, see this website.
When you get this error when starting openHAB (or another application using MQTT)
2025-03-29 15:35:40.709 [ERROR] [.io.transport.mqtt.MqttService] - Error starting broker connection
org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:75) ~[na:na]
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:538) ~[na:na]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_311]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_311]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476) ~[na:1.8.0_311]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218) ~[na:1.8.0_311]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200) ~[na:1.8.0_311]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) ~[na:1.8.0_311]
at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_311]
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:66) ~[na:na]
it means you cannot connect to the server from "outside" the mosquitto environment (tests with mosquitto client will work though). This has been introduced from version 2.0.0 of MQTT onwards for security reasons.
To allow "external" connections to the server you have to adapt/create the following file as sudo:
/etc/mosquitto/conf.d/mosquitto.conf (create as sudo if needed)
Add the following two lines to the file
allow_anonymous true
listener 1883 0.0.0.0
The first line allows anonymous connections while the second line allows "all" IP addresses to port 1883, which is the default MQTT port.
This should resolve the issue.
Restart the mqtt broker to be sure the updated configuration is taken into accound: sudo systemctl restart mosquitto.service
Then, as a crosscheck, see for the status of the mqtt broker: systemctl status mosquitto.service
You should see something like this:
pi@pizero2:~/mystuff/openHAB $ systemctl status mosquitto.service
● mosquitto.service - Mosquitto MQTT Broker
Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enab>
Active: active (running) since Sun 2025-09-14 13:52:23 CEST; 6 days ago
Docs: man:mosquitto.conf(5)
man:mosquitto(8)
Process: 391 ExecStartPre=/bin/mkdir -m 740 -p /var/log/mosquitto (code=exited, stat>
Process: 398 ExecStartPre=/bin/chown mosquitto /var/log/mosquitto (code=exited, stat>
Process: 401 ExecStartPre=/bin/mkdir -m 740 -p /run/mosquitto (code=exited, status=0>
Process: 402 ExecStartPre=/bin/chown mosquitto /run/mosquitto (code=exited, status=0>
Main PID: 403 (mosquitto)
Tasks: 1 (limit: 2057)
CPU: 2.305s
CGroup: /system.slice/mosquitto.service
└─403 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
Sep 14 13:52:23 pizero2 systemd[1]: Starting Mosquitto MQTT Broker...
Sep 14 13:52:23 pizero2 mosquitto[403]: 1757850743: Loading config file /etc/mosquitto/c>
Sep 14 13:52:23 pizero2 systemd[1]: Started Mosquitto MQTT Broker.
This proves all is working fine:
it says "active (running)" (see blue in above output listing)
it has loaded the modified file indirectly, via /etc/mosquitto/mosquitto.conf which loads all files inside the directory conf.d that ends with a .conf file extension.
To control the state of the MQTT service, you have the following options:
Check if the MQTT service is running:
systemctl status mosquitto.service
Starting the MQTT service:
sudo systemctl start mosquitto.service
Stopping the MQTT service:
sudo systemctl stop mosquitto.service
Enabling the MQTT service:
sudo systemctl enable mosquitto.service
This will automatically start the service at the next boot
This command will not start the MQTT service. Therefore, you have to run sudo systemctl start mosquitto.service
Disabling the MQTT service:
sudo systemctl disable mosquitto.service
This will prevent the MQTT service from auto-starting the next boot.
This command will not stop the currently running service. Therefore, you have to run sudo systemctl stop mosquitto.service