Why Does MQTT Engine 5.0.0 Retain the Sparkplug STATE Topic?

Daniel Price6 min read
HMI / SCADAOther ManufacturerTroubleshooting
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

MQTT Engine sends a connection request from Ignition 8.3 through the host network interface and intervening network devices to the EMQX listener. After the broker accepts the connection, the module requests its Sparkplug topic subscriptions. In MQTT Engine 5.0.0, filtering spBv1.0/# can leave the separate spBv1.0/STATE/IamHost path active when Primary Host is enabled. Build the commissioning test from the physical path upward, then remove that feature from the active configuration set.

Does the TCP path reach the correct EMQX listener?

Layer one first. Confirm link status at the Ignition host, then follow the packet through every routed or switched boundary to the EMQX endpoint. A topic-setting change cannot correct a failed name lookup, closed listener, routing error, TLS mismatch, or blocked transport port.

Path item Value to inspect Proof
Ignition source Host interface and route used for the broker address The route selects an active interface and reaches the expected destination.
Broker address The hostname or IP configured in MQTT Engine Name resolution and the EMQX listener address agree.
Broker port The configured server port It matches the active EMQX listener. Read the configured value; no port number is specified for this installation.
Transport security Plain or TLS transport as configured at both ends The client and listener use the same transport mode.
Connection timing Configured connect, keepalive, and reconnect values Read these values from the server configuration before interpreting repeated connection attempts; no exact timings are specified.

Check: Confirm that a connection attempt reaches the intended EMQX listener before changing namespace settings.

At which MQTT exchange does connectivity stop?

Separate transport failure from subscription failure. A successful socket connection proves only the network path. Follow the MQTT exchange in the broker log or a permitted packet capture: client connection, broker acknowledgement, subscription request, and broker response. With encrypted transport, use the endpoint logs because an intermediate capture cannot expose topic strings.

If the broker never records a connection, return to address, port, routing, and transport security. If it accepts the client and then records a rejected subscription or disconnect, compare the requested topic strings with the broker policy. Look specifically for both spBv1.0/# and spBv1.0/STATE/IamHost. Do not treat a connected socket as proof that every requested topic was accepted.

Observed stopping point Diagnostic branch Next check
No connection reaches EMQX Physical, route, address, port, or listener problem Prove reachability to the configured listener.
Connection reaches EMQX but is not accepted Transport or connection configuration Compare client and listener settings.
Connection succeeds, then subscription handling fails Topic request or broker authorization Record the exact requested topic and broker response.
General Sparkplug request disappears but STATE remains Primary Host path remains active Test a set with that option disabled.

Check: Identify the last successful exchange and capture the exact topic involved before editing the configuration.

Why does the filtered namespace leave the STATE topic?

As an MQTT wildcard, spBv1.0/# covers every descendant below spBv1.0/, including spBv1.0/STATE/IamHost. The MQTT Engine setting is therefore not behaving as a universal broker-side wildcard exclusion in this case. The observed result in version 5.0.0 is narrower: it removes the general spBv1.0/# request while the host-state request remains.

The deciding setting is Primary Host. A configuration set with this feature enabled can maintain the separate STATE-topic path even after the general Sparkplug namespace is filtered. For this installation, creating a new set without Primary Host removed the obstacle to connectivity with EMQX.

Configuration Observed or required topic behavior Decision
Filtered namespace applied; Primary Host enabled spBv1.0/# is filtered, but spBv1.0/STATE/IamHost remains Not suitable when the STATE topic must also be absent.
New set; Primary Host disabled The installation regained broker connectivity Use this configuration when primary-host behavior is not required.

Check: Inspect the active set, not merely the server-level filter, and confirm whether Primary Host is enabled.

How should the replacement set be configured?

Preserve the known network and authentication values while changing only the setting that controls the remaining state path. A new set makes the test reversible and prevents unrelated changes from obscuring the result.

  1. Record the current EMQX address, port, transport mode, client identity, authentication configuration, and filtered namespace value.
  2. Create a new configuration set in MQTT Engine 5.0.0.
  3. Copy only the connection values required to reach the same EMQX listener.
  4. Apply the required Sparkplug namespace filtering in the new set.
  5. Leave Primary Host disabled. Do not enter or retain a host-state configuration that recreates the unwanted path.
  6. Make the new set active for the test connection using the module's normal configuration workflow.
  7. Initiate a controlled reconnect and watch the MQTT Engine diagnostics and EMQX connection log together.

If the application requires primary-host semantics, disabling the feature changes that architecture. In that case, the broker policy and the required STATE-topic traffic must be reconciled instead of suppressing the feature.

Check: Confirm that the connection uses the new set and that the saved set shows Primary Host disabled.

Which commissioning mistakes can hide the result?

A cached or still-active connection can make a saved change appear ineffective. Verify which configuration instance owns the live session, then reconnect it through the normal module controls. Avoid changing filters, broker policy, credentials, and network settings in one test; a successful connection would not identify which change mattered.

Pitfall Misleading symptom Correction
Editing an inactive set The STATE request continues unchanged Trace the live server connection back to its selected set.
Testing an existing session Broker logs show old subscription state Perform one controlled reconnect after saving.
Changing several variables Connectivity returns with no isolated cause Hold the endpoint and credentials constant; change Primary Host only.
Checking only module status A socket appears connected while a topic is rejected Correlate module diagnostics with EMQX subscription records.
Assuming wildcard meaning equals product-filter scope spBv1.0/STATE/IamHost is unexpected Verify every emitted subscription rather than inferring it from spBv1.0/#.

Check: Run one test with identical connection values and only the Primary Host state changed.

How is the end-to-end fix verified?

  1. Start with no live test session, then activate the new set.
  2. Confirm that the Ignition host opens a connection to the configured EMQX address and port.
  3. Confirm that EMQX accepts the client connection.
  4. Inspect the subscription activity and verify that spBv1.0/# is filtered as intended.
  5. Verify that no request for spBv1.0/STATE/IamHost appears.
  6. Confirm that MQTT Engine remains connected instead of entering a reconnect cycle.
  7. Exercise the application data path that must remain available and confirm that its required topics still pass.

Check: The fix passes only when the broker session stays connected, the unwanted STATE topic is absent, and required application traffic still moves end to end.

FAQ

Why does MQTT Engine still request spBv1.0/STATE/IamHost?

In MQTT Engine 5.0.0, the filtered namespace can remove spBv1.0/# while the separate state path remains active with Primary Host. Use a new set with Primary Host disabled when that STATE request must be absent.

Why does EMQX connectivity fail after the socket connects?

A successful transport connection can be followed by subscription handling that the broker rejects. Check the broker log for the exact requested topic and determine whether spBv1.0/STATE/IamHost is the stopping point.

How do I prove the MQTT Engine filter change worked?

Reconnect with the new set, confirm that EMQX accepts and retains the session, verify that spBv1.0/STATE/IamHost is absent from the subscription activity, and pass required application traffic end to end.

Back to blog