Glossary · Modelling

Structure / ExtensionObject

In OPC UA, a Structure is a DataType with named fields, and an ExtensionObject is the wire container that carries one: an encoding NodeId plus the encoded body. Any value whose type the client cannot resolve arrives as an opaque ExtensionObject, which is what a failed custom-struct decode actually looks like.

Structure is the abstract root

Structure at i=22 is an abstract DataType. Every structured value in OPC UA derives from it - the standard ones such as Range, EUInformation, Argument and BuildInfo, and every structure a companion specification or a vendor defines. A Variable whose DataType attribute names a subtype of Structure carries its value inside a Variant as an ExtensionObject; there is no other way to move a structured value over the wire.

The three parts of an ExtensionObject

An ExtensionObject is a TypeId, an encoding byte and a body. The TypeId is the NodeId of the encoding node, not of the DataType node - the Default Binary, Default XML or Default JSON child reached from the DataType by a HasEncoding reference. The encoding byte says whether the body is absent, a ByteString of UA Binary, or an XmlElement. A decoder therefore keys its lookup table on encoding NodeIds, which is why a client that resolved the DataType but never followed HasEncoding still cannot decode anything.

Nested and array structures

Fields may themselves be structures, arrays of structures, or fields declared with an abstract DataType so that any subtype may appear. The last case is the expensive one: the decoder has to read the nested ExtensionObject's own TypeId before it knows what it is holding, and code generators either handle it explicitly or fall back to leaving the field as a raw ExtensionObject. UA-ModelCompiler's -useAllowSubtypes switch exists for exactly this.

What decoding failure looks like

Failure is rarely loud. A client with no type information usually returns the value as a byte blob with a TypeId and Good status, so the read succeeds and the data is useless - the umati dashboard client documents custom DataTypes as only partially working for exactly this reason. Where the server can tell, it answers BadDataEncodingUnsupported for an encoding it cannot produce or BadStructureMissing when the structure definition is unavailable; a truncated or mismatched body surfaces as BadDecodingError.

Example

One structured value on the wire, and the nodes a decoder must resolve first

Nodes
  Variable  ns=6;s=Line3.MC01.CurrentStep
    DataType -> ns=1;i=3002  (RecipeStep, subtype of Structure i=22)
  DataType   ns=1;i=3002
    --HasEncoding--> ns=1;i=5002   BrowseName 0:"Default Binary"
    --HasEncoding--> ns=1;i=5003   BrowseName 0:"Default XML"
    DataTypeDefinition -> StructureDefinition { StepNumber, Setpoint, Comment? }

What arrives in the DataValue
  Variant
    ExtensionObject
      TypeId       ns=1;i=5002        <- the ENCODING node, not i=3002
      Encoding     1                  <- body is a ByteString of UA Binary
      Body         01 00 00 00  00 00 00 00 00 00 45 40  01 ...

Decoded, once the definition is known
  StepNumber = 1
  Setpoint   = 42.0
  Comment    = present (optional-field mask bit 0 set)

Without the definition, a client returns the Body bytes and Good.
The mistake people make: Building the decoder lookup on the DataType NodeId. The TypeId on the wire is the encoding node's NodeId, so the table never matches and every structured value falls through to the opaque path - with a Good StatusCode, so nothing in the logs says anything is wrong. Follow HasEncoding from the DataType and key on Default Binary or Default JSON.

Defined in: Part 3 - Address Space Model for Structure DataTypes and encoding nodes; Part 6 - Mappings for the ExtensionObject encoding.

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Server Acceptance Test Pack
A 40-check acceptance test you run against a vendor's server before commissioning sign-off. Weighted scoring, three hard gates, and a one-page verdict for the supplier meeting.
Get the free test pack →
Free, no course, no login