MQTT.js icon indicating copy to clipboard operation
MQTT.js copied to clipboard

Client <unknown> disconnected due to protocol error.

Open pavankumarkl opened this issue 5 years ago • 13 comments

I am using MQTT and below are options that I am passing to connect

var options = { keepalive: 10, clientId: '', protocolId: 'MQTT', protocolVersion: 3, clean: true, reconnectPeriod: 20000, connectTimeout: 30 * 1000, protocol:'mqtt', rejectUnauthorized: false

} const client = mqtt.connect('mqtt://192.168.127.13:1883',options); -> my local mosquitto broker

can any one help, why I am getting "Client disconnected due to protocol error."

AB#9368700

pavankumarkl avatar Dec 16 '19 09:12 pavankumarkl

same here Any update?

const us = {
    clientId: 'xiot_' + Math.random().toString(16).substr(2, 8),
    username: mqtt.username,
    password: mqtt.password,
    useSSL: false,
    onSuccess: onAction,
    onFailure: onAction,
    protocolId: 'MQTT',
    protocolVersion: 5,
    rejectUnauthorized: false,
    clean: true,
    reconnectPeriod: 20000,
    connectTimeout: 30 * 1000,
    protocol: 'mqtt',
  };
  let client1 = mqtt1.connect('mqtt://192.168.1.16:1883/',us);

MShokry avatar Feb 06 '20 10:02 MShokry

Same here!

fabien-lg avatar Feb 18 '20 02:02 fabien-lg

So I had the same issue, new mosquitto server installed on OSX with homebrew and using react-native.

For some reason no native mqtt connection could be made so I used websockets.

You'll need to add to mosquitto.conf bellow #port 1883

listener 1883
protocol mqtt

listener 8883
protocol websockets 

When you start mosquitto it should say:

1583550048: mosquitto version 1.6.8 starting
1583550048: Config loaded from /usr/local/etc/mosquitto/mosquitto.conf.
1583550048: Opening ipv6 listen socket on port 1883.
1583550048: Opening ipv4 listen socket on port 1883.

Then connect using:

const client = mqtt.connect('ws://localhost:8883', options);

Hope this helps someone.

ghost avatar Mar 07 '20 03:03 ghost

I was getting the error "Client disconnected due to protocol error" in the below scenario:

  1. Mosquitto broker started without specifying any certs (cafile, certfile and keyfile) in the mosquitto config file.
  2. Mosquitto client (pub or sub) tries to connect to the above broker using proper certificates.

Fix: Review the mosquitto.conf file. Specify the proper certificates to be used by the broker for authenticating the clients (sub or pub)

naanuswaroop avatar Apr 09 '20 12:04 naanuswaroop

Just to add a trail of this, you will also encounter a protocol error if you try to use a subscription_identifier that's not between the allowed range 1 ~ 2^28-1

edocod1 avatar May 28 '20 21:05 edocod1

same here Any update?

const us = {
    clientId: 'xiot_' + Math.random().toString(16).substr(2, 8),
    username: mqtt.username,
    password: mqtt.password,
    useSSL: false,
    onSuccess: onAction,
    onFailure: onAction,
    protocolId: 'MQTT',
    protocolVersion: 5,
    rejectUnauthorized: false,
    clean: true,
    reconnectPeriod: 20000,
    connectTimeout: 30 * 1000,
    protocol: 'mqtt',
  };
  let client1 = mqtt1.connect('mqtt://192.168.1.16:1883/',us);

Same Issue for me, when I try to use the Websocket solution it works but i'm not in charge of the mosquitto server. I would like to use native MQTT protocol for this.

PaulCorbeau avatar Dec 14 '20 10:12 PaulCorbeau

bump?

bikeidaho avatar Feb 19 '21 20:02 bikeidaho

seems like a pervasive bug. it might be related to some bugs that have been recently fixed in mqtt-packet. It looks like a new version of mqtt-packet (patch-update) was released today. Can you try and see if you're using it and if the problem persists? The mqtt-packet version is 6.8.1.

YoDaMa avatar Feb 19 '21 21:02 YoDaMa

Hello! Any updates on this? I seem to have the same issue.

mehai avatar Mar 30 '21 17:03 mehai

seems like a pervasive bug. it might be related to some bugs that have been recently fixed in mqtt-packet. It looks like a new version of mqtt-packet (patch-update) was released today. Can you try and see if you're using it and if the problem persists? The mqtt-packet version is 6.8.1.

I used the 6.9.0 version when I found the bug.

mehai avatar Mar 30 '21 18:03 mehai

So I had the same issue, new mosquitto server installed on OSX with homebrew and using react-native.

For some reason no native mqtt connection could be made so I used websockets.

You'll need to add to mosquitto.conf bellow #port 1883

listener 1883
protocol mqtt

listener 8883
protocol websockets 

When you start mosquitto it should say:

1583550048: mosquitto version 1.6.8 starting
1583550048: Config loaded from /usr/local/etc/mosquitto/mosquitto.conf.
1583550048: Opening ipv6 listen socket on port 1883.
1583550048: Opening ipv4 listen socket on port 1883.

Then connect using:

const client = mqtt.connect('ws://localhost:8883', options);

Hope this helps someone.

Yup, this worked. 🎉🎉

SibiAkkash avatar May 23 '21 10:05 SibiAkkash

For working, I had to add this to my mosquito.conf:

  listener 1883
  allow_anonymous true
  protocol mqtt

  listener 9001
  protocol websockets

bjoernh avatar Aug 15 '21 20:08 bjoernh

Hi currently I'm facing protocol error

Client auto-4CBAFA0E-999-20099-DA44-AB775FF164BC disconnected: Protocol error.

before that I'm facing these error Client connection from 10.130.15.124 failed: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

this is current log Sending PINGRESP to c0a801f3e88e621764ed 1645700843: Client auto-953906E9-D8CA-9C29-8333-C37F09F0873C disconnected: Protocol error. 1645700843: Received PUBLISH from auto-2278FF4F-32D7-AD17-96A9-A552617B55C6 (d0, q1, r0, m32, 'BWG/spa/uplink', ... (130 bytes)) 1645700843: Sending PUBLISH to 0a820f49d3cb6217044e (d0, q1, r0, m4100, 'BWG/spa/uplink', ... (130 bytes)) 1645700843: Sending PUBACK to auto-2278FF4F-32D7-AD17-96A9-A552617B55C6 (m32, rc0) 1645700843: Received PUBACK from 0a820f49d3cb6217044e (Mid: 4100, RC:0)

mosquitto.conf --------------

use_identity_as_username true allow_anonymous true allow_zero_length_clientid true log_type all connection_messages true max_connections -1 protocol mqtt #protocol websockets

persistence true persistence_location /var/lib/mosquitto/ log_dest file /var/log/mosquitto/mosquitto6.log

listener 8883 0.0.0.0 pid_file /var/run/mosquitto/mosquitto.pid

cafile /etc/mosquitto/certs/xyz.pem certfile /etc/mosquitto/certs/xyz.pem keyfile /etc/mosquitto/certs/xyz.pem capath /etc/mosquitto/certs require_certificate true tls_version tlsv1.2

shivneutral avatar Feb 24 '22 11:02 shivneutral

I got this when using + in the topic. MQTT.js seems to be ok with this, however Mosquitto is not.

The specs disallow usage of wildcard characters in topics, so maybe MQTT.js should throw an error before it is sent? https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc385349267

pbackx avatar Nov 09 '22 08:11 pbackx

Hi. I managed to get MQTT to work over TLS. I also received the protocol error when trying to connect onto the secure port 8883. The problem was with creating the certificates. What fixed it was signing the certificates with the broker ip address as the Common Name. So if your broker is running on "192.56.1.0", you would put "192.56.1.0" as the Common Name for all of the signed certificates.

Commands I used to generate the certificates: openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 1826 -key ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -out server.csr -key server.key openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360

Make sure that you sign the Common Name properly I also made the Organizational Unit Names in the server and client certificate different

My mosquitto.conf is as follows:

listener 1883 allow_anonymous true protocol mqtt

listener 8883 protocol mqtt cafile /etc/mosquitto/certs/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key

tls_version tlsv1.2

I ran the broker using: moquitto -c mosquitto.conf -v

Subscribed to the secure network using: mosquitto_sub -h <broker_address> -p 8883 -t "<topic>" --cafile /etc/mosquitto/certs/ca.crt

Published to the secure network using: mosquitto_pub -h <broker_address> -p 8883 -t "<topic>" --cafile /etc/mosquitto/certs/ca.crt -m "<message>"

Hopefully this helps someone

bowenlin1101 avatar May 25 '23 14:05 bowenlin1101

bowenlin1101 >> L O V E - Y O U R - W O R K !

mthorley2020 avatar Jun 07 '23 10:06 mthorley2020

Hi. I managed to get MQTT to work over TLS. I also received the protocol error when trying to connect onto the secure port 8883. The problem was with creating the certificates. What fixed it was signing the certificates with the broker ip address as the Common Name. So if your broker is running on "192.56.1.0", you would put "192.56.1.0" as the Common Name for all of the signed certificates.

Commands I used to generate the certificates: openssl genrsa -des3 -out ca.key 2048 openssl req -new -x509 -days 1826 -key ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -out server.csr -key server.key openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 360

Make sure that you sign the Common Name properly I also made the Organizational Unit Names in the server and client certificate different

My mosquitto.conf is as follows:

listener 1883 allow_anonymous true protocol mqtt

listener 8883 protocol mqtt cafile /etc/mosquitto/certs/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key

tls_version tlsv1.2

I ran the broker using: moquitto -c mosquitto.conf -v

Subscribed to the secure network using: mosquitto_sub -h <broker_address> -p 8883 -t "<topic>" --cafile /etc/mosquitto/certs/ca.crt

Published to the secure network using: mosquitto_pub -h <broker_address> -p 8883 -t "<topic>" --cafile /etc/mosquitto/certs/ca.crt -m "<message>"

Hopefully this helps someone

i am following your steps but i am in windows C:\Program Files\mosquitto>mosquitto_sub --cafile "C:\Program Files\mosquitto\certs\ca.crt" -h 10.244.2.216 --tls-version tlsv1.2 -p 8883 -t "test" -d Client null sending CONNECT Error: protocol error

i am getting this error

sheran29 avatar Jul 04 '23 04:07 sheran29

Try to reproduce the issue with MQTT v5 and feel free to reopen in case the bug persists

robertsLando avatar Jul 31 '23 15:07 robertsLando

Ok, so I came across the same issue yesterday: the server responded with:

Client <unknown> disconnected due to protocol error

Thankfully, I have full access to both the server and the client, so I started doing a little digging.

I was running the script with Bun, so I did:

DEBUG='mqttjs*' bun run test

On a different project in the same monorepo (that was behaving properly), I had this output:

  mqttjs connecting to an MQTT broker... +0ms
  mqttjs:client MqttClient :: options.protocol mqtt +0ms
  mqttjs:client MqttClient :: options.protocolVersion 4 +0ms
  mqttjs:client MqttClient :: options.username undefined +0ms
  mqttjs:client MqttClient :: options.keepalive 60 +0ms (...)

but on my test project which looked like this:

const serverUrl = "mqtt://my.server.com:1883";

function init() {
  const mqtt = require("mqtt");
  const mqttClient = mqtt.connect(serverUrl);

  mqttClient.on("connect", () => {
    console.log("connected to mqtt server");
    mqttClient.subscribe("#", (err) => {
      if (err) console.log(err);
    });
  });
  mqttClient.on("close", () => {
    console.log("closed");
  });
  mqttClient.on("error", (err) => {
    console.log(err);
  });
  mqttClient.on("message", (_topic, message) => {
    console.log(message.toString());
  });
}

init();

the debug output was:

  mqttjs connecting to an MQTT broker... +0ms
  mqttjs:client MqttClient :: options.protocol ws +0ms
  mqttjs:client MqttClient :: options.protocolVersion 4 +0ms
  mqttjs:client MqttClient :: options.username undefined +0ms
  mqttjs:client MqttClient :: options.keepalive 60 +0ms

So, I stepped in the connect function and in mqtt/build/lib/connect/index.js the is_browser_1 returns true! Which means that MQTT is immediately excluded from being added in the protocols object. And further down the line, when the time comes to make a protocol decision, you only get WS. Which would account for the behavior that most people in this thread noticed: a connection dropped due to protocol error which is magically fixed when the server is changed to support WS connections.

So, the tl;dr is that the offending piece of code (at least in my case) is the following:

const isBrowser = (typeof window !== 'undefined' && typeof window.document !== 'undefined') ||
    (typeof self !== 'undefined' && typeof self.postMessage === 'function');

After printing out the individual parts of the isBrowser expression, it turns out that typeof self is an object and typeof self.postMessage is actually a function.

And so, the isBrowser constant becomes true, and things go downhill from there.

From what I understand, the second check is there to determine if we are in a web worker context.

I didn't have time to go any deeper, but a possible solution for this would be to skip the browser check if the protocol is defined in the options object: assume that the user knows what he is doing and go from there.

Cheers!

f1234k avatar Oct 24 '23 14:10 f1234k

@f1234k could you describe the environment from which you are running mqttjs? bun? browser? nodejs?

robertsLando avatar Oct 24 '23 15:10 robertsLando

@robertsLando It's Bun. The command is bun run test.js. Bun version is 1.0.6.

The contents of the test.js file is exactly what I pasted above: 24 lines.

f1234k avatar Oct 24 '23 15:10 f1234k

Tested with bun 1.0.7 and issue still exists.

Steps to minimally reproduce the issue:

  1. bun init -> Enter -> test.js
  2. bun install mqtt
  3. vim test.js
const serverUrl = "mqtt://my.server.com:1883";

function init() {
  const mqtt = require("mqtt");
  const mqttClient = mqtt.connect(serverUrl);

  mqttClient.on("connect", () => {
    console.log("connected to mqtt server");
    mqttClient.subscribe("#", (err) => {
      if (err) console.log(err);
    });
  });
  mqttClient.on("close", () => {
    console.log("closed");
  });
  mqttClient.on("error", (err) => {
    console.log(err);
  });
  mqttClient.on("message", (_topic, message) => {
    console.log(message.toString());
  });
}

init();
  1. bun run test.js

If the server does not support WS connections, you get the disconnected due to protocol error message in your MQTT broker's (i.e., Mosquitto) logs.

Edit: you can run DEBUG='mqttjs*' bun run test.js and see the options.protocol being set to ws (happens even if you pass an options object because of the isBrowser check that I mentioned).

f1234k avatar Oct 24 '23 15:10 f1234k

question is how to propely detect bun env and distinguish it from web worker, wouyld you like to submit a PR?

robertsLando avatar Oct 24 '23 15:10 robertsLando

@robertsLando sure. Let me look into this a bit further.

f1234k avatar Oct 24 '23 15:10 f1234k

@robertsLando Done.

f1234k avatar Oct 24 '23 16:10 f1234k

Hi all, i'm facing the same issue using mqtt library from client side with react. I don't get why using the same code from (for example) Bun, like:

// connect to MQTT broker
const client = mqtt.connect("mqtt://localhost:1883");
client.on("connect", () => {
    console.log("Connected to MQTT broker");
    // subscribe to the topic
    client.subscribe("/sensors/temperature");
});

// handle MQTT messages
client.on("message", (topic, message) => {
    console.log("Message received: ", message.toString());
});

it works as expected, while using it from client side (browser web-worker i assume) i receive the:

Client disconnected due to protocol error.

In order to make it work, i had to add the WebSockets protocol on port 8883 on the mosquito conf file, as suggested above.

const client = mqtt.connect('mqtt://localhost:8883'})
        client.on('connect', () => {
            console.log('connected to mqtt broker: ', broker);
        });

Can someone please explain to me why this is required from the client side and not from Node/Bun? Thanks in advance to those who will help me!

Michele-x98 avatar Nov 22 '23 15:11 Michele-x98

On browsers the only protocol that works is websocket, this is not an MQTTjs limitation but it's a browser limitation

robertsLando avatar Nov 22 '23 16:11 robertsLando

So this means that every mqtt connection is upgraded automatically to a websocket connection from browser, while this does not happen on Machine-to-Machine connection, right?. Is there any way from broker side to apply a port forwarding from mqtt exposed port protocol to the websocket one?

Michele-x98 avatar Nov 22 '23 16:11 Michele-x98

So this means that every mqtt connection is upgraded automatically to a websocket connection from browser, while this does not happen on Machine-to-Machine connection, right?.

Correct

Is there any way from broker side to apply a port forwarding from mqtt exposed port protocol to the websocket one?

It depends on the broker you are using but I think that should be possible

robertsLando avatar Nov 22 '23 16:11 robertsLando

Thanks for the fast reply and explanation! i'm using Mosquitto, I'll take a look at the documentation if it's possible to do it.

Michele-x98 avatar Nov 22 '23 16:11 Michele-x98