Glossary · Modelling

Optional fields

In OPC UA, optional fields are Structure fields that may be present or absent per value. A structure declaring them has StructureType StructureWithOptionalFields, and its binary encoding begins with a UInt32 bit mask, one bit per optional field in declaration order, saying which are actually present.

Per value, not per server

This is the distinction that catches people. An Optional modelling rule decides whether a node exists on an instance, once, when the server builds its address space. An optional structure field is decided per value: the same Variable can return a structure with the field present at 08:00 and absent at 08:01. A decoder must therefore read the mask on every value, not learn the shape once and cache it.

The encoding mask

In UA Binary a StructureWithOptionalFields value starts with a UInt32 EncodingMask. Bit 0 corresponds to the first optional field in declaration order, bit 1 to the second, and mandatory fields consume no bits. A field whose bit is clear contributes no bytes at all to the body - the field is skipped, not zero-filled. Get the bit-to-field mapping wrong and the body is parsed at the wrong offsets, which corrupts every field after it.

Absent is not a default value

An absent optional field means the server has nothing to say, which is semantically different from zero, empty string or epoch. Mapping absence to a default is how a null timestamp becomes 1970 in a historian and a missing tolerance becomes a tolerance of zero in a quality calculation. Represent absence explicitly in your own data model and let the consumer decide, rather than filling it in at the decoder.

In JSON encodings

The mask is a binary-encoding construct. In reversible JSON an absent optional field is simply not emitted as a member, and in non-reversible JSON the omission is indistinguishable from a field the encoder dropped for other reasons. If you consume structures over JSON PubSub, decide up front whether a missing member means absent-by-design or lost-in-encoding, because the payload alone will not tell you.

Example

The same structure encoded with and without its optional fields

Definition (StructureType = StructureWithOptionalFields)
  ns=1;i=3020  PartResult
    PartId      String            mandatory
    Measured    Double            mandatory
    Tolerance   Double            optional  -> mask bit 0
    Comment     LocalizedText     optional  -> mask bit 1

Value A - both optional fields present
  EncodingMask  0x00000003
  PartId        "P-4471"
  Measured      10.021
  Tolerance     0.05
  Comment       "reworked"

Value B - tolerance only
  EncodingMask  0x00000001
  PartId        "P-4472"
  Measured      10.004
  Tolerance     0.05
  (no bytes at all for Comment)

Value C - neither
  EncodingMask  0x00000000
  PartId        "P-4473"
  Measured      9.998

In nodeset XML
  <Field Name="Tolerance" DataType="i=11" IsOptional="true"/>
  <Field Name="Comment"   DataType="i=21" IsOptional="true"/>
The mistake people make: Testing a custom-struct decoder against one sample value. The server sends every optional field while the machine is running normally, the decoder looks correct, and the first value with a cleared mask bit - typically an error or idle state - shifts every subsequent field. Generate test values with each mask combination, and always drive field offsets from the mask rather than from the declaration order alone.

Defined in: Part 3 - Address Space Model, StructureField and the IsOptional flag; Part 6 - Mappings for the optional-field encoding mask.

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