# Failed to handle Sparkplug B message

**URL:** <https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460>\
**Category:** MQTT Modules\
**Tags:** mqtt-engine\
**Created:** [November 1, 2023, 10:55pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460 "2023-11-01T22:55:05Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlordiales](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.cirrus-link.com/jlordiales/32/209_2.png) [@jlordiales](https://forum.cirrus-link.com/u/jlordiales)\
**Post date:** [November 1, 2023, 10:55pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/1 "2023-11-01T22:55:05Z")

</div>

Hi all,  
I’m currently trying to run the Java reference host application from [here](https://github.com/eclipse/tahu/tree/master/java/compat_impl/host) in order to read/write tags to a local Ignition instance. I’m running MQTT Engine and Transmission 4.0.18 (b2023081122).

The host application is successfully reading the tag changes but when I try to send a CMD to write a value based on the example they have on the README, MQTT Engine seems to be failing to parse it.

This is the message sent to MQTT according to the Host Application:

```auto
Message [topic=spBv1.0/JoseLocal/NCMD/E0, payload=SparkplugBPayload [timestamp=1698877483000, metrics=[Metric [name=Writeable/WriteableBoolean2, alias=null, timestamp=1698877483000, dataType=Boolean, isHistorical=null, isTransient=null, metaData=null, properties=null, value=true, isNull=false]], seq=null, uuid=null, body=null]]

```

But when MQTT Engine tries to parse it it’s failing with:

```auto
Warning [CirrusSparkplugUtil] - Received invalid payload - trying to decode with legacy decoder

Error [SparkplugBPayloadDecoder] - Failed to decode the payload on metric datatype: name: "Writeable/WriteableBoolean2" timestamp: 1698877483000 is_null: false boolean_value: true 

Error [EngineCallback] - java.lang.Exception: Failed to decode: Unknown MetricDataType 0
at com.cirruslink.common.sparkplug.util.LegacyArraySparkplugBDecoder.getMetricValue(LegacyArraySparkplugBDecoder.java:358)
at com.cirruslink.common.sparkplug.util.LegacyArraySparkplugBDecoder.convertMetric(LegacyArraySparkplugBDecoder.java:103)
at com.cirruslink.common.sparkplug.util.LegacyArraySparkplugBDecoder.buildFromByteArray(LegacyArraySparkplugBDecoder.java:73)
at com.cirruslink.common.sparkplug.util.LegacyArraySparkplugBDecoder.buildFromByteArray(LegacyArraySparkplugBDecoder.java:49)
at com.cirruslink.common.sparkplug.util.CirrusSparkplugUtil.decodePayload(CirrusSparkplugUtil.java:71)
at com.cirruslink.common.sparkplug.util.CirrusSparkplugUtil.decodePayload(CirrusSparkplugUtil.java:40)
at com.cirruslink.common.sparkplug.util.CirrusSparkplugUtil.decodePayload(CirrusSparkplugUtil.java:92)
at com.cirruslink.mqtt.engine.gateway.sparkplug.SparkplugBPayloadHandler.decodePayload(SparkplugBPayloadHandler.java:202)
at com.cirruslink.mqtt.engine.gateway.sparkplug.SparkplugBPayloadHandler.decodePayload(SparkplugBPayloadHandler.java:134)
at com.cirruslink.mqtt.engine.gateway.sparkplug.SparkplugPayloadHandler.handlePayload(SparkplugPayloadHandler.java:150)
at com.cirruslink.mqtt.engine.gateway.EngineCallback.lambda$messageArrived$3(EngineCallback.java:338)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

```

Not sure if I’m doing something wrong in the command payload itself or I’m missing some configuration somewhere.  
Any help would be appreciated!

---

<div class="post-metadata">

**Author:** ![wes.johnson](https://avatars.discourse-cdn.com/v4/letter/w/f14d63/32.png) [@wes.johnson](https://forum.cirrus-link.com/u/wes.johnson)\
**Post date:** [November 1, 2023, 10:58pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/2 "2023-11-01T22:58:21Z")

</div>

This is due to a bug in MQTT Engine v4.0.18. It doesn’t properly handle CMD messages missing metric data types in the payload. However, this can be safely ignored as MQTT Engine doesn’t act on CMD messages anyway. In v4.0.19 you will no longer see this error message though.

---

<div class="post-metadata">

**Author:** ![jlordiales](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.cirrus-link.com/jlordiales/32/209_2.png) [@jlordiales](https://forum.cirrus-link.com/u/jlordiales)\
**Post date:** [November 1, 2023, 11:02pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/3 "2023-11-01T23:02:40Z")

</div>

Thanks Wes.

Just for my understanding (I’m just getting started with Ignition), if MQTT Engine doesn’t act on CMD messages, how would a Host Application update tag values via MQTT? Who’s responsible for acting on those? Transmission?

---

<div class="post-metadata">

**Author:** ![wes.johnson](https://avatars.discourse-cdn.com/v4/letter/w/f14d63/32.png) [@wes.johnson](https://forum.cirrus-link.com/u/wes.johnson)\
**Post date:** [November 1, 2023, 11:26pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/4 "2023-11-01T23:26:46Z")

</div>

Yes - Host applications like MQTT Engine or the Tahu Host Application send CMD messages. Transmission (or other Edge Node implementations) receive that CMD, write to the output, get the new updated value, send it back to the Host Application(s) via a DATA message. At this point, Engine would update its value of that corresponding tag. You might want to take a look at this doc and leave custom implementations out of the mix to start: [Getting Started: Two Ignition Architecture - MQTT Modules for Ignition 8.x - Confluence](https://docs.chariot.io/display/CLD80/Getting+Started%3A+Two+Ignition+Architecture)

---

<div class="post-metadata">

**Author:** ![jlordiales](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.cirrus-link.com/jlordiales/32/209_2.png) [@jlordiales](https://forum.cirrus-link.com/u/jlordiales)\
**Post date:** [November 2, 2023, 12:50am UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/5 "2023-11-02T00:50:45Z")

</div>

So if I uninstall the MQTT Engine and try to send the same NCMD payload I still get the decoding error from `SparkplugBPayloadDecoder`: `Failed to decode the payload on metric datatype: name: "WriteableBoolean2" timestamp: 1698885026000 is_null: false boolean_value: true `.

Which then causes the Transmission module to fail as well:

```auto
java.lang.NullPointerException: Cannot invoke "org.eclipse.tahu.message.model.Metric.getName()" because "metric" is null
at com.cirruslink.mqtt.transmission.gateway.sparkplug.SparkplugMqttCallback$MessageArrivedWorker.run(SparkplugMqttCallback.java:262)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

```

Would that be a bug in the Tahu lib?

---

<div class="post-metadata">

**Author:** ![wes.johnson](https://avatars.discourse-cdn.com/v4/letter/w/f14d63/32.png) [@wes.johnson](https://forum.cirrus-link.com/u/wes.johnson)\
**Post date:** [November 2, 2023, 2:03am UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/6 "2023-11-02T02:03:28Z")

</div>

Ah sorry - I misunderstood. I thought you were saying that Exception came from MQTT Engine. I actually fixed this on the develop branch of Tahu very recently here: [Added EdgeNodeMetricMaps class for handling datatype lookups in Edge Nodes by wes-johnson · Pull Request #320 · eclipse/tahu · GitHub](https://github.com/eclipse/tahu/pull/320). This will be included in the next release of Transmission 4.0.19 (likely early next week).

---

<div class="post-metadata">

**Author:** ![wes.johnson](https://avatars.discourse-cdn.com/v4/letter/w/f14d63/32.png) [@wes.johnson](https://forum.cirrus-link.com/u/wes.johnson)\
**Post date:** [November 2, 2023, 2:04am UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/7 "2023-11-02T02:04:22Z")

</div>

It is already in the nightly build of Transmission here: [Nightly Module Builds - MQTT Modules for Ignition 8.x - Confluence](https://docs.chariot.io/display/CLD80/Nightly+Module+Builds)

---

<div class="post-metadata">

**Author:** ![jlordiales](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.cirrus-link.com/jlordiales/32/209_2.png) [@jlordiales](https://forum.cirrus-link.com/u/jlordiales)\
**Post date:** [November 2, 2023, 2:14pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/8 "2023-11-02T14:14:26Z")

</div>

Thanks Wes! I can confirm that the nightly build doesn’t fail when parsing the CMD and I can see the change reflected in the tag!

This is unrelated to my original question but I did notice that when the Tahu Host Application requests a rebirth for the edge node (either sending that explicitly as per the example in the README or as part of the ordering mechanism) there’s an Exception in the Transmission module with:

```auto
java.lang.NullPointerException: Cannot invoke "org.eclipse.tahu.message.model.MetricDataType.toIntValue()" because the return value of "org.eclipse.tahu.model.MetricDataTypeMap.getMetricDataType(String)" is null
at org.eclipse.tahu.message.SparkplugBPayloadDecoder.getMetricValue(SparkplugBPayloadDecoder.java:228)
at org.eclipse.tahu.message.SparkplugBPayloadDecoder.convertMetric(SparkplugBPayloadDecoder.java:123)
at org.eclipse.tahu.message.SparkplugBPayloadDecoder.buildFromByteArray(SparkplugBPayloadDecoder.java:84)
at org.eclipse.tahu.message.SparkplugBPayloadDecoder.buildFromByteArray(SparkplugBPayloadDecoder.java:56)
at com.cirruslink.mqtt.transmission.gateway.sparkplug.SparkplugMqttCallback$MessageArrivedWorker.run(SparkplugMqttCallback.java:241)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)

```

The payload of the CMD sent there is

```auto
Message [topic=spBv1.0/JoseLocal/NCMD/E0, payload=SparkplugBPayload [timestamp=1698934276000, metrics=[Metric [name=Node Control/Rebirth, alias=null, timestamp=1698934276000, dataType=Boolean, isHistorical=null, isTransient=null, metaData=null, properties=null, value=true, isNull=false]], seq=null, uuid=null, body=null]]

```

---

<div class="post-metadata">

**Author:** ![wes.johnson](https://avatars.discourse-cdn.com/v4/letter/w/f14d63/32.png) [@wes.johnson](https://forum.cirrus-link.com/u/wes.johnson)\
**Post date:** [November 6, 2023, 6:57pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/9 "2023-11-06T18:57:52Z")

</div>

This was a bug. I has been fixed in the nightly module and will be included in the v4.0.19 version of the module.

---

<div class="post-metadata">

**Author:** ![Elena](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.cirrus-link.com/elena/32/327_2.png) [@Elena](https://forum.cirrus-link.com/u/Elena)\
**Post date:** [March 6, 2025, 1:09pm UTC](https://forum.cirrus-link.com/t/failed-to-handle-sparkplug-b-message/460/10 "2025-03-06T13:09:18Z")

</div>

Hi,

I use MQTT Module version 4.0.25, but I get such kind of messages  
I am trying to write to MQTT tags, but in Logger I get Errors:

![image](https://canada1.discourse-cdn.com/flex028/uploads/cirrus_link/original/1X/2727574a30faac6158717712e59f40d0451170e2.png)

I can read tags, but I can’t write to tags.

UPDATED:  
I found the solution  
In Ignition **Gateway/Config/MQTT ENGINE/Servers/Sparkplug B** I set the “Include Sparkplug DataTypes” to True and it works
