Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client <unknown> disconnected due to protocol error. #1021

Closed
pavankumarkl opened this issue Dec 16, 2019 · 30 comments
Closed

Client <unknown> disconnected due to protocol error. #1021

pavankumarkl opened this issue Dec 16, 2019 · 30 comments
Labels

Comments

@pavankumarkl
Copy link

pavankumarkl commented Dec 16, 2019

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

@MShokry
Copy link

MShokry commented Feb 6, 2020

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);

@fabien-lg
Copy link

Same here!

@ghost
Copy link

ghost commented Mar 7, 2020

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.

@naanuswaroop
Copy link

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)

@edocod1
Copy link

edocod1 commented May 28, 2020

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

@PaulCorbeau
Copy link

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.

@bikeidaho
Copy link

bump?

@YoDaMa
Copy link
Contributor

YoDaMa commented Feb 19, 2021

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 YoDaMa added the bug label Feb 19, 2021
@YoDaMa YoDaMa self-assigned this Feb 19, 2021
@mehai
Copy link

mehai commented Mar 30, 2021

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

@mehai
Copy link

mehai commented Mar 30, 2021

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.

@SibiAkkash
Copy link

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. 🎉🎉

@bjoernh
Copy link

bjoernh commented Aug 15, 2021

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

  listener 1883
  allow_anonymous true
  protocol mqtt

  listener 9001
  protocol websockets

@shivneutral
Copy link

shivneutral commented Feb 24, 2022

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

@pbackx
Copy link

pbackx commented Nov 9, 2022

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

@bowenlin1101
Copy link

bowenlin1101 commented May 25, 2023

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

@mthorley2020

This comment was marked as off-topic.

@sheran29
Copy link

sheran29 commented Jul 4, 2023

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

@robertsLando
Copy link
Member

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

@f1234k
Copy link
Contributor

f1234k commented Oct 24, 2023

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!

@robertsLando
Copy link
Member

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

@f1234k
Copy link
Contributor

f1234k commented Oct 24, 2023

@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
Copy link
Contributor

f1234k commented Oct 24, 2023

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).

@robertsLando
Copy link
Member

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

@f1234k
Copy link
Contributor

f1234k commented Oct 24, 2023

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

@f1234k
Copy link
Contributor

f1234k commented Oct 24, 2023

@robertsLando Done.

@Michele-x98
Copy link

Michele-x98 commented Nov 22, 2023

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!

@robertsLando
Copy link
Member

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

@Michele-x98
Copy link

Michele-x98 commented Nov 22, 2023

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?

@robertsLando
Copy link
Member

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

@Michele-x98
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests