BadDecodingError
BadEncoding
BadDecodingError means the receiving side could not parse the bytes it was given. It is almost always a type mismatch between what the sender encoded and what the receiver expected: a stale structure definition, an unknown encoding id, or a truncated message. Reload the server's type information before blaming the network.
What you actually see
A specific node or a specific service call fails to decode while everything else on the same session works, or a client throws a decoding exception mid-stream and drops the connection.
Why it happens
- Client decoding a structure with the wrong definitionIf the client's idea of a structure - field order, field types, optional-field mask - does not match the server's, the bytes are read as the wrong types and decoding fails partway through. Type bindings generated from an older model version against an upgraded server are the classic case.
- Encoding id not known to the receiverAn ExtensionObject names its content by encoding NodeId. If the client never loaded that type, a good stack returns the raw body as an opaque ExtensionObject, but a client that tries to decode it eagerly, or that resolved the wrong id after a namespace reindex, fails outright.
- Legacy type dictionary versus DataTypeDefinition mismatchA server that offers only the legacy binary type dictionary, talking to a client that only supports DataTypeDefinition, leaves structures undecoded. The reverse pairing does the same. This migration is still live in the field, so mixed estates hit it regularly.
- Truncated or corrupted messageA chunked message that lost a chunk, a proxy or deep-packet-inspection device that altered the stream, or a stack bug in chunk reassembly all produce bytes that stop making sense partway through. This form usually kills the channel rather than one request.
- Non-conforming server encodingSome embedded servers encode a field slightly out of spec - a wrong array length prefix, a LocalizedText mask that does not match the fields present, a string length in the wrong units. Strict clients refuse it while lenient ones happen to cope, which is why one tool works and another does not.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Narrow it to one node or one serviceRead nodes individually rather than in a batch until you find the one that fails. If it is a structured node, the problem is type information. If it is an ordinary scalar, look at chunking and the transport.
- Reload the server's type informationLoad DataTypeDefinition from the DataType nodes at connect time, or the legacy type dictionary if that is all the server offers. Do not carry compiled structure definitions from a previous firmware or a different companion specification release.
- Check whether the server offers definitions your client can consumeBrowse the DataType node for a DataTypeDefinition attribute, and browse for a type dictionary under the Types folder. If the server has only the dictionary and your client only understands definitions, you will get undecoded ExtensionObjects and the fix is a client capable of both.
- Capture the exchange in WiresharkThe OPC UA dissector shows where decoding stops. A message that is well formed up to a specific field points at a type mismatch; a message that is short or has an inconsistent chunk sequence points at transport corruption.
- Rule out the pathIf decoding fails intermittently and kills the channel, test through a direct connection with no proxy, firewall inspection or gateway in the way. Deep-packet inspection on port 4840 is a real cause of altered streams in plant networks.
- Raise decoding limits only after excluding type problemsA limits problem reports as BadEncodingLimitsExceeded, not as a decoding error, so raising limits here is usually wasted effort. Treat it as a last resort.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| asyncua (Python) | Call await client.load_data_type_definitions() after connecting so structures decode into generated Python classes. Without it, custom structures arrive as ExtensionObjects and any attempt to interpret them yields a decoding failure. |
| UA-.NETStandard (C#) | ComplexTypeSystem.Load builds runtime types from the server. A ServiceResultException with BadDecodingError on a structured read almost always means the type system was not loaded or was loaded before a namespace change. |
| node-opcua | The client fetches extension object definitions during session creation. If the server publishes both a dictionary and definitions and they disagree, node-opcua may decode fields into the wrong order - compare a decoded value against the same node read in UaExpert. |
| Eclipse Milo | DataTypeDictionary and DataTypeDefinition are handled separately. A server offering only the legacy dictionary needs the dictionary reader enabled; otherwise structures stay as opaque ExtensionObjects. |
| open62541 (C) | Custom types must be registered in the client's custom data type array. An unregistered encoding id yields an ExtensionObject that decodes to nothing useful rather than a hard failure, so check for empty bodies as well as faults. |
| UaExpert | If UaExpert decodes the structure and your client does not, the server is fine and your client's type handling is the problem. That single comparison saves a great deal of packet capture. |
What it looks like in the log
BadDecodingError while decoding ExtensionObject with TypeId ns=4;i=5006
ServiceFault: BadDecodingError - unexpected end of stream at offset 214
Custom structure decoded with unknown encoding id; falling back to raw ExtensionObject
Confirm the fix
Read the previously failing structured node and confirm every field decodes to a plausible value, not just that the call returns Good - a wrong field order can decode without error and produce nonsense.
Stop it happening again
Load type information from the live server at every connect, and version-check the model: read the namespace URI and the model version node where the companion specification provides one, then refuse to start if it differs from what your bindings expect.
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.