Resolving NullReferenceException in Rapid SCADA KpMQTT Driver

Jason IP6 min read
Other ManufacturerSCADA ConfigurationTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Resolving NullReferenceException in Rapid SCADA KpMQTT Driver

The Rapid SCADA KpMQTT driver is a community-maintained communication module that bridges MQTT brokers into the Rapid SCADA 5/6 channel model. Field deployments frequently surface a single, recurring .NET runtime fault during the first poll cycle:

System.NullReferenceException: Object reference not set to an instance of an object. (In Spanish-localized installs the message reads: "referencia a objeto no establecida como instancia de un objeto".)

The exception is thrown inside the Communicator service before any input channel number (Cnl) is mapped to a tag, which means the failure is almost always in the device template (DevTemplate) or in the supporting driver assemblies, not in the topic payload itself. This reference document walks through root cause analysis, file-level remediation, and verification procedures using the official Rapid SCADA 6 source tree as the canonical implementation reference.

1. Affected Versions and Components

Component Affected Versions Status
KpMQTT driver DLL Pre-release builds on bersim/OpenKPs KpMQTT Community supported
Rapid SCADA Server 5.x and 6.x branch See RapidScada/scada-v6
Communicator service ScadaComm.exe / ScadaCommunicator Runs under ServerUser account
Configuration database BaseDAT.xml, DevTemplate.xml XML, UTF-8 encoded

The KpMQTT driver is distributed as a set of compiled .NET DLLs that must be unblocked on Windows before the .NET runtime will JIT-load them. A blocked assembly silently loads into the AppDomain and then throws NullReferenceException on the first property access, which is the most common cause reported by integrators deploying the driver for the first time.

2. Root Cause Analysis

The exception is generated by the Common Language Runtime when an object dereference is performed on a null reference. In the KpMQTT driver, the following four conditions have been observed in production deployments:

  1. Blocked driver DLLs downloaded from GitHub. Windows marks files with the Zone.Identifier alternate data stream as "from the internet"; the .NET loader initializes the type but skips IL verification, then fails on the first member access.
  2. Missing or malformed <MqttParams> section. Empty UserName/Password tags combined with a defined Port cause the MqttClient constructor branch to dereference an uninitialized credential object.
  3. Empty <MqttSubTopics> collection. The driver subscribes during Init(); if no <Topic> nodes exist, the internal subscription list is null and the next poll cycle raises the exception.
  4. Unresolved NumCnl. The NumCnl value (e.g., 1020) must already exist in BaseDAT.xml. A channel number not registered in the device's input channel table causes the tag-binding routine to dereference a null tag descriptor.

3. Required XML Schema

A valid DevTemplate for the KpMQTT driver follows the schema below. Each section is mandatory; an empty tag must still be present.

<?xml version="1.0" encoding="UTF-8"?>
<DevTemplate>
  <MqttParams Password="" UserName="" Port="1883" ClientID="KpMQTTrs111" Hostname="192.168.1.106"/>
  <RapSrvCnf ServerPwd="12345" ServerUser="ScadaComm" ServerPort="10000" ServerHost="127.0.0.1"/>
  <MqttSubTopics>
    <Topic NumCnl="1020" QosLevel="0" TopicName="ha/_temperature1"/>
  </MqttSubTopics>
</DevTemplate>
Element Attribute Required Description
<MqttParams> Hostname Yes Broker IP or DNS name (e.g., 192.168.1.106)
<MqttParams> Port Yes TCP listener port, default 1883 (TLS 8883)
<MqttParams> ClientID Yes Must be unique on the broker
<MqttParams> UserName No Leave blank for anonymous brokers
<MqttParams> Password No Leave blank for anonymous brokers
<RapSrvCnf> ServerHost Yes Rapid SCADA Server listening address
<RapSrvCnf> ServerPort Yes Default 10000
<RapSrvCnf> ServerUser Yes Communicator service account
<RapSrvCnf> ServerPwd Yes Communicator service password
<Topic> TopicName Yes MQTT subscription filter
<Topic> NumCnl Yes Input channel number to bind
<Topic> QosLevel Yes 0, 1, or 2 per MQTT spec

4. Prerequisites

  • Rapid SCADA Server 5.x or 6.x installed and running (verify with RapidScada/scada-v6 release notes for current build).
  • Administrator rights on the Windows host to unblock DLLs and modify C:\SCADA\ directory.
  • An MQTT broker reachable on the network (Mosquitto, EMQX, HiveMQ, or cloud-hosted).
  • The KpMQTT driver package from bersim/OpenKPs.
  • Text editor capable of saving UTF-8 XML without BOM (Notepad++, VS Code).

5. Step-by-Step Remediation

5.1 Unblock the Driver DLLs

  1. Right-click each DLL in the KpMQTT distribution folder (typically KpMQTT.dll, M2Mqtt.dll).
  2. Select Properties.
  3. On the General tab, check Unblock at the bottom.
  4. Click Apply and OK.

For unattended deployment, run from an elevated PowerShell prompt:

Get-ChildItem "C:\SCADA\KP\*" -Recurse -Include *.dll | Unblock-File

5.2 Validate the Device Template

  1. Open the device's DevTemplate XML in the Communicator configuration table editor.
  2. Confirm the <MqttSubTopics> section contains at least one <Topic> node.
  3. Confirm every NumCnl value exists in BaseDAT.xml input channels of the same device.
  4. Verify Hostname resolves via ping or Test-NetConnection -Port 1883 (PowerShell).

5.3 Register the Input Channel

Each MQTT topic must be paired with a valid input channel. In the Rapid SCADA Administrator:

  1. Open the device's input channels table.
  2. Add a row with Cnl = 1020, signal type appropriate to the payload (typically 1 = Analog or 0 = Discrete).
  3. Set the tag formula if transformation is required (e.g., scaling x*0.1 for °C/10 raw values).

5.4 Restart the Communicator Service

net stop ScadaCommunicator
net start ScadaCommunicator

6. Verification Procedure

  1. Open the Rapid SCADA Communicator log at C:\SCADA\ScadaComm\Log\. Confirm no NullReferenceException entries appear within 60 seconds of service start.
  2. From the broker host, publish a test payload: mosquitto_pub -h 192.168.1.106 -t ha/_temperature1 -m "23.5"
  3. In Rapid SCADA Webstation, navigate to the channel 1020 view. The current value should update within the configured poll interval.
  4. Check the event log for Data received entries tied to channel 1020.

7. Diagnostic Matrix

Symptom Likely Cause Fix
NullReferenceException on start Blocked DLLs Unblock per section 5.1
NullReferenceException on first poll Empty MqttSubTopics Add at least one <Topic>
Exception mentions NumCnl value Channel not registered Create the channel in BaseDAT
Connection refused in log Wrong port or firewall Verify Port=1883, open firewall
Auth failed Wrong UserName/Password Populate credentials in XML
Spanish-language exception text Localized OS .NET runtime Fault is identical; fix root cause

8. Network and Security Considerations

Port 1883 is the unencrypted MQTT default. For production deployments, use TLS on 8883 and provide CA certificate paths in the <MqttParams> extension attributes supported by M2Mqtt. Ensure Windows Firewall inbound rules allow the Communicator host to reach the broker port. If the broker is on a different VLAN, verify routing and that the ServerUser account has local policy rights to create outbound TCP sockets.

9. Migrating to Rapid SCADA 6

The RapidScada/scada-v6 repository is the modern .NET 6+ rewrite. Drivers built against the v5 KP API are not directly compatible; the KpMQTT driver requires a v6-compatible recompile using the new IDriver interface declared in Scada.Comm.Drivers. Channel binding is now performed through the CnlTagFactory rather than NumCnl attribute lookup. Plan migration by:

  1. Exporting the v5 DevTemplate to JSON.
  2. Recompiling KpMQTT against the v6 SDK.
  3. Remapping topic-to-channel bindings via the new Configuration application.

10. Best Practices

  • Always unblock DLLs immediately after extracting the GitHub ZIP.
  • Keep ClientID unique per device instance to avoid broker kicks.
  • Set QosLevel = 1 for sensor data requiring at-least-once delivery.
  • Restrict ServerUser privileges; the ScadaComm account only needs write access to the channel database.
  • Use a wildcard topic filter (e.g., ha/+/temperature) only when the downstream channel mapping is verified.
If the NullReferenceException persists after applying all remediation steps, capture a full Communicator stack trace and open an issue on the KpMQTT driver repository with the XML configuration attached. Never share live credentials.

FAQ

What causes "Object reference not set to an instance of an object" in KpMQTT?

The exception is a .NET NullReferenceException raised when the driver dereferences an uninitialized object, most commonly because the KpMQTT DLLs were downloaded with the Windows "blocked" flag, the MqttSubTopics section is empty, or the referenced NumCnl does not exist in BaseDAT.xml.

How do I unblock KpMQTT DLLs on Windows?

Right-click each DLL, choose Properties, check "Unblock" on the General tab, and apply. From PowerShell run Get-ChildItem "C:\SCADA\KP\*" -Recurse -Include *.dll | Unblock-File.

Where is the KpMQTT DevTemplate file located?

It is stored inside the Communicator configuration database for each device, typically under C:\SCADA\BaseDAT\. The XML must include <MqttParams>, <RapSrvCnf>, and at least one <Topic> inside <MqttSubTopics>.

Is KpMQTT compatible with Rapid SCADA 6?

Not directly. The v5 KP API uses NumCnl bindings that were replaced in v6 by CnlTagFactory. Recompile KpMQTT against the v6 SDK from the RapidScada/scada-v6 repository.

How do I verify the MQTT driver is working after a fix?

Publish a test payload with mosquitto_pub to the configured topic, then view channel 1020 in Rapid SCADA Webstation. The Communicator log should show "Data received" without NullReferenceException entries within 60 seconds of service start.

Back to blog