Status code · Data access

BadStructureMissing

BadCustom structs

BadStructureMissing means a required structured parameter was absent from the request the client sent. In practice it points at a client that omitted a mandatory field - a filter, a request header member, a settings structure - rather than at anything wrong on the server. Capture the request and compare it against the service definition.

Defined behaviour: A mandatory structured parameter was missing from the request, or a structure required to interpret the value was not supplied. (our description of the condition this code reports)

What you actually see

A service call fails immediately with BadStructureMissing and no per-item results, usually the first time a hand-built or generated request is used.

Why it happens

  • A mandatory sub-structure left null in a hand-built requestSeveral services take structures inside structures: MonitoredItemCreateRequest carries a ReadValueId and MonitoringParameters, HistoryReadDetails carries an ExtensionObject of the right details type. Leaving one of these null rather than default-constructed produces a request the server cannot process.
  • ExtensionObject sent with an encoding id but no bodyWhere a service parameter is an ExtensionObject - history read details, a filter, a settings structure - the encoding NodeId identifies the type and the body carries the fields. An empty or absent body is a missing structure even though the type was correctly named.
  • Custom structure written without its field valuesWhen writing a structured value, every mandatory field of the structure must be present in the encoded body. A client that built the ExtensionObject from an incomplete object graph, or that omitted fields it considered optional but the DataTypeDefinition marks mandatory, sends an incomplete structure.
  • Client and server disagree about which fields are optionalOptional fields in a 1.04-and-later structure are governed by an encoding mask. If the client was generated from an older version of the type, or from a different companion specification release, the mask and the field set do not line up and the server sees a mandatory field as absent.
  • Generated code from a stale NodeSetType bindings generated from a NodeSet2 export taken before the server was upgraded can omit a field the newer model added as mandatory. The client compiles and runs and only fails against the upgraded server.

How to fix it

In diagnostic order: work down, do not skip ahead.

  1. Capture the failing request on the wireWireshark decodes OPC UA binary requests field by field. Compare what actually left the client against the service definition for the call you are making. A null where a structure should be is visible immediately and saves a long guessing exercise.
  2. Default-construct rather than null every nested structureWhere an SDK exposes a nullable structure member, construct an empty instance instead of leaving it null unless the service explicitly permits absence. This resolves most hand-built request failures without needing to know which member was at fault.
  3. Reload the server's type definitions before writing structuresRead DataTypeDefinition from the DataType node and use it to enumerate the mandatory fields. If your client cannot load the definition, do not attempt the write - you cannot construct a correct body without it.
  4. Regenerate type bindings from the current server NodeSetExport the server's address space, or fetch the companion specification release the server implements, and regenerate. A binding built from a different model version is the usual explanation when the same code worked against a previous firmware.
  5. Check the optional-field encoding maskFor structures with optional fields, the mask must correspond to the fields actually encoded. Setting a bit without supplying the field, or supplying a field without setting the bit, produces a body the server cannot parse into a complete structure.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UA-.NETStandard (C#)Service request classes have nullable structure members. MonitoringParameters, RequestHeader and details ExtensionObjects should be constructed, not left null. ComplexTypeSystem-generated types carry the correct field set for the server you loaded them from.
asyncua (Python)load_data_type_definitions() creates Python dataclasses matching the server's structures, including optional-field handling. Building an ExtensionObject by hand with a partial dict is where this code comes from.
node-opcuaThe extension object factory constructs structures from the server's data type definitions. Passing a plain object with missing mandatory members to the constructor yields an under-populated encoding rather than a client-side error.
Eclipse MiloDynamicStructs built from DataTypeDefinition enforce the field list. Hand-rolled ExtensionObject bodies bypass that check and are the usual source of a missing-structure fault.
open62541 (C)UA_ExtensionObject with an encoding id but a zero-length body is accepted by the client and rejected by the server. Use the generated types from the server's nodeset via the nodeset compiler rather than assembling bodies manually.
OPC PublisherAdvanced event filters and history details are supplied as structured configuration. An incomplete select or where clause definition in the configuration file surfaces as a structured-parameter fault at subscription creation.

What it looks like in the log

ServiceFault: BadStructureMissing on CreateMonitoredItems
Write to ns=6;s=Recipe failed: BadStructureMissing - mandatory field Quantity absent from encoded structure
HistoryRead rejected: details ExtensionObject body was empty

Confirm the fix

Repeat the call with the corrected request and confirm a Good service result, then read back any structure you wrote and check that every mandatory field carries the value you intended rather than a type default.

Stop it happening again

Generate structure bindings from the server's own DataTypeDefinition at connect time rather than compiling them from a snapshot, and add a startup check that compares the loaded field set against what your code expects.

Verify before you rely on this: Servers vary in whether an incomplete structure is reported as BadStructureMissing, BadDecodingError or BadInvalidArgument. Treat all three as the same class of client-side encoding fault when diagnosing.

Stuck on more than one of these? The troubleshooting clinic works through broken configurations end to end, on camera.

Troubleshooting clinic →

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 Status Code Diagnostic Tree
A 15-page diagnostic reference grouping every normative status code by what actually went wrong: with the first action for each, and the four questions that resolve most faults before you read a single code.
Get the free diagnostic tree →
Free, no course, no login