0

I try to generate a new device and publish some random data to it via MQTT. I follow this official example: https://cumulocity.com/guides/device-sdk/mqtt-examples/#hello-mqtt-cs

All operations are executed without any error. Even establishing connection. But when I try to publish a message to the device I get the following error

"Connecting with MQTT server failed (ConnectionRefusedNotAuthorized)"

Here is my info to connect to the server

        const string serverUrl = "mytenant.eu-latest.cumulocity.com";
        const string clientId = "d:testdevice4";
        const string device_name = "testdevice4";
        const string user = "<mytenant>.eu-latest/<myusername>";
        const string password = "XXXXXXXX";

And here are the operations that are executed without throwing any exception or ConnectionFailed event:

Establish Connection

        await client.EstablishConnectionAsync();

Create Device

        string topic = "s/us";
        string payload = $"100,{device_name}, c8y_MQTTDevice";
        var message = new MqttMessageRequestBuilder()
            .WithTopicName(topic)
            .WithQoS(QoS.EXACTLY_ONCE)
            .WithMessageContent(payload)
            .Build();

The other operations on Cumulocity Example

        // set device's hardware information
        var deviceMessage = new MqttMessageRequestBuilder()
            .WithTopicName("s/us")
            .WithQoS(QoS.EXACTLY_ONCE)
            .WithMessageContent($"110, {device_name}, MQTT test model, Rev0.1")
            .Build();

        await client.PublishAsync(deviceMessage);

        // add restart operation
        await client.SubscribeAsync(new MqttMessageRequest() { TopicName = "s/ds" });
        await client.SubscribeAsync(new MqttMessageRequest() { TopicName = "s/e" });
        await client.PublishAsync(new MqttMessageRequestBuilder()
            .WithTopicName("s/us")
            .WithQoS(QoS.EXACTLY_ONCE)
            .WithMessageContent("114,c8y_Restart")
            .Build());

But when I try to publish a message to the device as follows, ConnectionFailed event is invoked with the error:

"Connecting with MQTT server failed (ConnectionRefusedNotAuthorized)"

        Random rnd = new Random();
        while (!cToken.IsCancellationRequested)
        {
            int temp = rnd.Next(10, 20);
            Console.WriteLine("Sending temperature measurement (" + temp + "º) ...");
            var xx = client.ConnectionDetails;
            await client.PublishAsync(new MqttMessageRequestBuilder()
                .WithTopicName("s/us")
                .WithQoS(QoS.EXACTLY_ONCE)
                .WithMessageContent("211," + temp)
                .Build());
            Thread.Sleep(1000);
        }
mctuna
  • 809
  • 3
  • 19
  • 38
  • Their example has `string user = "<>/<>";`. Yours has `".eu-latest/";`. Are you sure that yours is correct? – canton7 Oct 23 '19 at 15:42
  • I have tried with and without .eu-latest. I have also tried username as email and alias name. All variations lead to the same error. I am not sure about clientId though. Is "d:" correct? – mctuna Oct 23 '19 at 15:47
  • If you have not solved it, we ran into the same problem. We solved it by making the broker the same host as our cockpit URL. The tenant in your case would be without the region. – Gambit Support Nov 04 '19 at 13:56
  • @GambitSupport thanks for your info. We strangely solved it by creating a totally new user, grant it with the necessary permission and use its credentials. – mctuna Nov 04 '19 at 15:41

2 Answers2

0

You get a ConnectionRefusedNotAuthorized error because your credentials are not correct. To be precise, the user:

const string user = "<mytenant>.eu-latest/<myusername>";

The user is formed as tenantID/username

Your tenant domain (<mytenant>.eu-latest) is not the tenant ID. Tenant IDs – in most of the cases – are a number preceded by the letter t, e.g. t123123.

so your string should look like:

const string user = "t123123/mytenant";

More details can be found in the public documentation:

Manasés Jesús
  • 103
  • 1
  • 2
  • 5
0

There could be more reasons than just authorization issues, as per

https://cumulocity.com/guides/device-sdk/mqtt/

which states for return code 5 - "Connection refused, not authorized"

Mostly a device side related problem, used when the device doesn’t have permissions or is doing something forbidden. For example, if the client sends malformed messages or tries to execute an operation without authenticating first, such as publishing a message. Thrown on any issue with certificate authentication (for example, wrong common name, failed auto registration). Also thrown on general issues with receiving device data or some other authorization problem related to the device state on the platform. For example, device managed object problems, or the sudden removal of permissions. In this situation it may be required to take action on the platform to investigate and apply a fix. When clientId is too long the user can receive this error when using 3.1 version of MQTT. This can happen if clientId has 24 characters or more. Lastly, it can also be thrown on unexpected exceptions like performance issues, especially during connection. Therefore it is a good approach to repeat the connection a few times to overcome temporary performance issues.

I had the same issue where all my coded attempts (C#, Node.js) were failing with this same error.

In my case I am using a trial Cumulocity environment where the tenant id differs from all the Cumulocity documentation (which says the tenant id starts with a 't' followed by a number of digits. In my trial environment, the Tenant ID is shown in the Cumulocity Cockpit under the user details (top right), and this is in the format "ENVxxxxxx".

To try to troubleshoot the issue I began testing with an online MQTT client http://www.emqx.io/online-mqtt-client and through this process I mistakenly typed the username with lower case "env" and this resolved my issue. Hope that helps others.