Search code examples
c#.net-coremqttmosquitto

The client has been disconnected while trying to perform the connection


When trying to connect to a Mosquitto MQTT queue running locally, I get the following error.

Unhandled exception. System.AggregateException: One or more errors occurred. (The client  has been disconnected while trying to perform the connection)
 ---> System.Net.Mqtt.MqttClientException: The client  has been disconnected while trying to perform the connection
   at System.Net.Mqtt.Sdk.MqttClientImpl.ConnectAsync(MqttClientCredentials credentials, MqttLastWill will, Boolean cleanSession)

I am using the default options when setting up the System.Net.Mqtt.MqttClient.

var config = new MqttConfiguration() {
  Port = 1883
};
var client = MqttClient.CreateAsync("localhost", config).Result;
var sessionState = client.ConnectAsync(
                new MqttClientCredentials(clientId: "camerasim")).Result;

The following errors show up in the Mosquitto MQTT log.

1644497589: New connection from 172.17.0.1:56792 on port 1883.

1644497589: New client connected from 172.17.0.1:56792 as camerasim (p2, c0, k0).

1644497589: Bad socket read/write on client camerasim: Invalid arguments provided.

Solution

  • The error you are seeing is most likely the result of a change made in Mosquitto 2.0.12:

    Fix max_keepalive not applying to MQTT v3.1.1 and v3.1 connections. These clients are now rejected if their keepalive value exceeds max_keepalive. This option allows CVE-2020-13849, which is for the MQTT v3.1.1 protocol itself rather than an implementation, to be addressed.

    A change made in 2.0.9 also comes into play:

    Fix max_keepalive option not applying to clients connecting with keepalive set to 0. Closes #2117.

    These changes were made to address an issue with the MQTT protocol itself which permits a denial of service attack (CVE-2020-13849).

    The default value for max_keepalive is 65535 so this change means that attempting to connect with keep alive set to 0 (meaning no keepalive) will fail unless mosquitto.conf specifies max_keepalive 0. Unfortunately the error logged (Bad socket read/write on client XXXXXYYYYY: Invalid arguments provided.) does not really highlight the cause.

    There are two available solutions:

    • Specify max_keepalive 0 in mosquitto.conf (Mosquitto 2.0.13 or later).
    • When connecting specify a keep alive between 1 and 65535. In xamarin/mqtt this means adding KeepAliveSecs to your config; this defaults to 0.

    Note that setting KeepAliveSecs = 1 (as per your answer) will allow you to connect but is probably a little short for most users (KeepAliveSecs = 60 may be more appropriate). e.g.

    var configuration = new MqttConfiguration {
        Port = 1883,
        KeepAliveSecs = 60,
        WaitTimeoutSecs = 2,
    };
    

    I realise that you have already found a solution to this but as it's likely to affect others I thought it was worth explaining the root cause of the issue. Many MQTT libraries default keep alive to 0 so will be impacted (e.g. Go Paho had an issue logged).