S7-1500 OPC UA Struct TypeInfo Decoding Errors: Ignition Fix

David Krause11 min read
OPC / OPC UASiemensTroubleshooting
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

Problem Overview

An S7-1500 OPC UA server, when paired with a client such as Ignition 8.3.1, can return ExtensionObject values that the Milo-based OPC UA stack cannot decode. The symptom is a tag that previously subscribed cleanly and rendered as a JSON struct in Ignition, suddenly appearing as an unreadable scalar or throwing a logged serialization fault. Existing PLC tags continue to work; only new tags, recently modified tags, or tags whose DB hosting was moved (for example Instance DB → Global DB) start to misbehave.

The error chain from the Ignition gateway log typically reads:

Error decoding ExtensionObject: ExtensionObject[body=ByteString[bytes=000000000000000000000000],
encodingId=NodeId{ns=3, id=TE_"misc"."Data"}]
org.eclipse.milo.opcua.stack.core.UaSerializationException:
no codec registered for encodingId=ns=3;s=TE_"misc"."Data"
    at org.eclipse.milo.opcua.stack.core.encoding.binary.OpcUaDefaultBinaryEncoding.decode(OpcUaDefaultBinaryEncoding.java:89)
    at org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject.lambda$decode$0(ExtensionObject.java:116)
    at com.inductiveautomation.ignition.gateway.opcua.OpcUaToIgnition.decodeExtensionObject(OpcUaConversions.kt:680)
    at com.inductiveautomation.ignition.gateway.opcua.OpcUaSubscriptionListener.onDataReceived(OpcUaSubscriptionManager.kt:506)

The controlling identifier is encodingId=ns=3;s=TE_"misc"."Data". Namespace 3 is the SIMATIC namespace injected by the S7-1500 OPC UA server, and the TE_ prefix indicates a TypeEncoding node that refers to a structured data type defined in the PLC's companion namespace. When the Milo stack has no codec registered for that encoding ID, the body remains an opaque ByteString of zeros (length 10, two-byte length prefix + eight-byte empty payload) and the subscription update fails to convert into a usable Ignition qualified value.

Root Cause Analysis

The S7-1500 OPC UA server exposes struct (UDT) data through two parallel mechanisms:

  1. The legacy DataType Dictionary (sometimes called "Deprecated DataType Dictionary Support"), which uses a single combined TypeDictionary node with binary-encoded descriptions.
  2. The modern DataTypeDefinition attribute on the DataType node itself, which encodes structure metadata directly on the type node.

When the PLC is configured to expose its types via the legacy DataType Dictionary path and the dictionary binary blob does not match the structure the client has cached, the encoding ID resolves but the stack cannot bind a decoder. The fault is therefore not a transport or authentication failure; it is a metadata consistency failure between the S7-1500 server's ns=3 type tree and what the client (Ignition) was led to expect at subscription time.

Three conditions on the PLC side reliably reproduce this symptom class:

  • A struct/UDT is edited in TIA Portal (member added, removed, renamed, reordered, or initial value changed) and the project is downloaded to the CPU while the OPC UA session is still open. The auto-reconnect does not always force a re-read of the dictionary.
  • A UDT that previously lived in an Instance DB (IDB) is moved into a Global DB (or vice versa) and downloaded. The encoding node ID path changes from TE_"DB_name"."StructName" to TE_"misc"."Data" or back, invalidating cached codecs.
  • Optimized block access is toggled on the affected DB, which changes the SIMATIC byte layout and the OPC UA structure description.

On the Ignition side, the relevant flag is the advanced OPC UA connection setting Deprecated DataType Dictionary Support. By default, this setting is true only on connections that were upgraded from Ignition 8.1.x; new connections in 8.3.x default to false. With the flag enabled, Ignition attempts to use the SIMATIC dictionary path, and any mismatch yields the codec exception above.

Affected Configurations and Versions

Component Verified Versions Notes
SIMATIC S7-1500 / S7-1500T CPU firmware V2.9 → V20 (TIA Portal V17–V20) TypeDictionary behavior set per OPC UA server interface in Properties → OPC UA → Server.
TIA Portal OPC UA companion namespace Companion spec namespace 3 (SIMATIC) Defines UDT encoding IDs prefixed TE_.
Inductive Automation Ignition 8.1.x → 8.3.1 (Milo stack 0.6.x) Deprecated DataType Dictionary Support flag introduced at 8.1.27.
OPC UA client (verification) UaExpert 1.7+, Prosys OPC UA Browser Used to confirm DataTypeDefinition attributes.

SIMATIC to OPC UA Data Type Mapping

SIMATIC data types do not map one-to-one to OPC UA built-ins. The PLC exposes a hybrid representation that includes SIMATIC-specific scalar and structure types in namespace 3. Use the mapping below to validate what the server should publish for each PLC-side declaration.

SIMATIC type (TIA) OPC UA type Encoding node prefix Notes
BOOL Boolean Direct mapping, no struct wrapper.
INT / DINT / LINT Int16 / Int32 / Int64 Signed integer mapping; check endianness on optimized DBs.
REAL / LREAL Float / Double IEEE-754; verify byte order after TIA download.
STRING (UTF-8 max 254) String Length prefix in OPC UA includes NUL terminator.
WSTRING String UTF-16; ensure client reads in UTF-16 mode.
DTL ExtensionObject (custom) TE_"misc"."DTL" First struct type commonly affected by codec failures.
UDT (PLC-side type) Structure DataType (ns=3) TE_"<DB>"."<UDT>" or TE_"misc"."Data" Encoding path changes when UDT moves between DBs.
ARRAY[..] OF <type> Structure or Array, depending on layout Per element Optimized block access may collapse inner layout.
STRUCT (non-UDT) Structure DataType TE_"<DB_name>"."StructName" Encoding ID includes DB name; renaming DB invalidates the codec.

Per Siemens documentation, the S7-1500 OPC UA server is required to publish all SIMATIC types in the SIMATIC companion namespace so that clients can resolve them; only OPC UA built-ins are reused without conversion. See Mapping SIMATIC data types to OPC UA data types (S7-1500 / S7-1500T) for the full matrix.

Diagnostic Procedure

Follow this sequence before making any change to isolate whether the fault is on the PLC side, the Ignition side, or both.

  1. Enable the Milo debug logger on Ignition. In the Gateway Webpage, navigate to Status → Diagnostics → Logs and set the logger opcua.gateway.OpcUaConversions to DEBUG. This surfaces the exact encoding ID, namespace URI, and body length for every ExtensionObject that the stack rejects. Reference: Changing Logging Levels — Ignition User Manual.
  2. Inspect the address space with UaExpert. Connect to the same OPC UA endpoint used by Ignition and browse Types → DataTypes. Open the offending node (for example ns=3;s=TE_"misc"."Data") and verify:
    • The DataTypeDefinition attribute is populated (Structure subtype with field list).
    • The Encoding reference resolves to a BinaryEncoding node whose TypeId points to a node that the client can decode.
    • The structure field count and order match the TIA Portal UDT definition.
  3. Compare server export with PLC definition. In TIA Portal, open Properties → OPC UA → Server → Export and export the server interface XML. Verify that every UADataType with a TE_ prefix has a matching definition in the running CPU project.
  4. Check namespace URI binding. In Ignition, open the OPC UA Connection → Edit → Servers → Endpoints and confirm that the namespace 3 URI exposed by the server matches what TIA Portal reports under OPC UA → Server → Namespaces. A mismatch indicates the CPU was loaded with a different project than the one TIA Portal is editing.
  5. Reproduce the fault deterministically. Note the timestamp of the first failing subscription update. Cross-reference it with the TIA Portal download history on the CPU's online backup. Any download event within ±60 s is suspect.

Resolution Steps

Fix 1 — Disable Deprecated DataType Dictionary Support in Ignition

  1. Open Config → OPC UA → Connections in the Gateway Webpage and select the affected Siemens connection.
  2. Click Edit, then click More → Advanced Settings.
  3. Set Deprecated DataType Dictionary Support to false.
  4. Click Save. Ignition will drop and re-establish the underlying Milo session, forcing a fresh read of the DataTypeDefinition attributes.
  5. Wait for the connection status to return to Connected and verify that the previously failing tags now resolve as JSON structs.
Field note: This setting restores correct decoding for UDTs placed in a Global DB. UDTs that are still declared inside an Instance DB may continue to fail because the encoding ID still references the instance path. Apply Fix 2 in that case.

Fix 2 — Move UDTs to Global DBs or Re-publish TypeDictionary

  1. In TIA Portal, declare a Global DB of the same UDT type and copy the data block content into it.
  2. Download only the hardware/software changes to the CPU (do not perform a full recompile if avoidable).
  3. In the OPC UA server properties, disable the Optimized block access attribute on the new Global DB if the UDT contains STRING, WSTRING, or arrays of structs. Optimized access changes byte alignment, which the S7-1500 OPC UA server reflects in the DataTypeDefinition and may still desynchronize the client.
  4. In Ignition, force a reconnect: open the OPC UA connection, click Edit, change the description by one character, Save. The reconnection will pull fresh type metadata.

Fix 3 — Server-side TypeDictionary Reset

  1. In TIA Portal, open Device Configuration → Properties → OPC UA → Server → Data access.
  2. Uncheck Use type dictionary (also called "Support deprecated DataTypeDictionary"). This forces the S7-1500 OPC UA server to expose only the modern DataTypeDefinition attributes.
  3. Compile and download to the CPU.
  4. Cycle the OPC UA server on the CPU: Online → Accessible devices → CPU → Online & Diagnostics → OPC UA → Stop, then Start. This invalidates all sessions.
  5. Reconnect from Ignition; the Milo stack will rebuild codecs against the new DataTypeDefinition tree.
Production caution: Disabling the type dictionary affects every OPC UA client connected to that CPU, including HMIs and historians. Schedule a maintenance window and notify all consumers before applying.

Fix 4 — Compensating Client Workaround (when server cannot be touched)

If the PLC is on a production line and cannot be re-downloaded, force Ignition to re-resolve codecs without restarting the Gateway:

  1. Disable the OPC UA connection in the Gateway Webpage.
  2. Wait 5 seconds for in-flight subscriptions to release.
  3. Re-enable the connection. The session is re-keyed and all type metadata is re-read.
  4. If the fault returns within minutes, the PLC server is publishing a self-inconsistent dictionary; only a server-side fix will hold.

Verification

After applying any fix above, confirm the resolution with the following checks:

  1. In the Ignition Designer, drag the previously failing tag onto a window. It should expand into a struct with named members rather than showing as an unreadable byte string.
  2. In the Ignition Gateway logs, search for UaSerializationException. The count should drop to zero within one publish interval (default 1 s).
  3. In UaExpert, subscribe to the same tag at 250 ms and verify stable values for at least 5 minutes. A return of Bad_DecodingError indicates the server is still publishing mismatched metadata.
  4. From the OPC UA client perspective, run Tools → Discover and confirm the DataTypeDefinition attribute on the encoding node resolves without a Bad_AttributeIdInvalid status code.
  5. If your project uses Ignition Tag History on these structs, verify that historical records populate without null values.

Prevention Checklist

Phase Action Effect
TIA Portal project design Place UDTs in Global DBs, not Instance DBs. Stabilizes encoding node IDs across DB renaming.
TIA Portal project design Disable "Optimized block access" on any DB containing STRING/WSTRING or nested structs consumed by OPC UA. Prevents byte-alignment-induced dictionary drift.
TIA Portal project design Disable the legacy TypeDictionary option unless an external client requires it. Eliminates the ns=3 dictionary failure path entirely.
Ignition connection setup Set "Deprecated DataType Dictionary Support" to false on every new S7-1500 connection. Routes decoding through DataTypeDefinition, the supported path.
Change management After any TIA Portal download that touches a DB used by OPC UA, force an Ignition reconnect. Refreshes cached codecs before a stale read corrupts history.
Monitoring Add a Gateway log alarm on UaSerializationException. Catches the failure class before a historian loses data.

Related Error Codes and Stack Traces

Code / Identifier Origin Meaning
Bad_DecodingError (0x80080000) OPC UA status code Server body cannot be decoded with any registered binary codec.
Bad_AttributeIdInvalid (0x80050000) OPC UA status code Server lacks DataTypeDefinition attribute on the type node.
16#8005_0000 (S7-1500 client-side, SFB / FB usage) Siemens S7-1500 OPC UA client instruction Reports a transport-level OPC UA fault returned from the remote server; not the same root cause but commonly searched together. Reference: Errors during the communication through an OPC UA Server from a 1515F-2 PLC (client).
no codec registered for encodingId=ns=3;s=... Milo stack Ignition-side manifestation of the same fault; verify the encoding ID against the live server namespace.

Cross-Platform Notes

The S7-1500 OPC UA server's namespace 3 + TE_ encoding scheme is not specific to Ignition. Any Milo-based client (including open-source libraries built on Eclipse Milo) and any .NET Standard stack tracking the OPC Foundation reference implementation will hit the same no codec registered exception under identical conditions. The .NET ecosystem has tracked equivalent issues on the OPC Foundation tracker, for example UA-.NETStandard issue #1066. Likewise, when an S7-1500 acts as the OPC UA client against a third-party server, the corresponding Siemens-side symptom appears in the diagnostic buffer of the OPC UA client instruction block; see OPC UA connection problem — S7-1500 client for an OMRON NX102 case study.

FAQ

Why do existing tags keep working after a TIA download but new tags break?

The Milo stack caches the decoder for each encoding ID the first time it decodes a value. Existing tags are still bound to the original codec; new tags encounter the post-download encoding node, which no longer matches the cached definition. A forced reconnect clears the cache.

Does "Deprecated DataType Dictionary Support = false" apply to all S7-1500 connections?

Yes, the toggle is per OPC UA connection in Ignition. Set it to false on every Siemens connection, whether the connection was created in 8.1.x or 8.3.x, to avoid the legacy dictionary path entirely.

What is the difference between Optimized and Non-Optimized block access for OPC UA structs?

Optimized access lets the S7-1500 reorder members in memory for performance and uses symbolic addressing only; non-optimized access preserves the declared byte layout. OPC UA publishes the layout it sees, so toggling the setting changes the DataTypeDefinition field offsets and will desynchronize cached client codecs.

Does moving a UDT from an Instance DB to a Global DB change the encoding node ID?

Yes. An Instance DB embeds the UDT under TE_"<DB_name>"."StructName", while a Global DB exposes it under a shared TE_"misc"."Data" or type-name reference. Any client holding the old encoding ID will fail until it reconnects and rebinds.

Can the OPC UA server on the S7-1500 be restarted without stopping the PLC?

Yes. In TIA Portal Online & Diagnostics, navigate to OPC UA → Stop/Start or use the web server of the CPU if enabled. The PLC scan continues; only OPC UA sessions are dropped and re-established.

Back to blog