Status code · Data access

BadTypeMismatch

BadVariant types

BadTypeMismatch means the Variant you wrote does not match the target node's declared DataType, ValueRank or ArrayDimensions. Read the node's DataType, ValueRank and ArrayDimensions attributes first, then build the Variant to match exactly - Int16 is not Int32, and a one-element array is not a scalar.

Defined behaviour: The value supplied for the attribute is not of the same type as the attribute's value, or is otherwise not compatible with the DataType, ValueRank and ArrayDimensions declared on the node. (our description of the condition this code reports)

What you actually see

A Write that looks correct returns BadTypeMismatch for one item while the other items in the same request succeed, and reading the same node back works fine.

Why it happens

  • Integer width or signedness differsThe node's DataType attribute says Int16, UInt32 or Byte, and the client sent a plain platform integer that the SDK encoded as Int32 or Int64. Nothing narrows the value for you: the server compares the Variant's built-in type identifier against the node's DataType and rejects the mismatch. This is the most common cause on PLC servers, where tag widths follow the PLC data type, not the language you are writing from.
  • Scalar versus array confusionValueRank on the node decides this. ValueRank -1 means scalar only, 1 means a one-dimensional array, and -2 or -3 mean any or scalar-or-array. Writing a one-element array to a ValueRank -1 node is a type mismatch even though the element type is right, and writing a scalar to a ValueRank 1 node fails the same way. ArrayDimensions can further pin the length, so a 10-element write to a node declared with ArrayDimensions of 8 is rejected as well.
  • Structure written as raw bytes or as the wrong structureFor a node whose DataType is a custom structure, the value must be an ExtensionObject carrying the correct encoding NodeId. If the client failed to resolve the DataTypeDefinition and fell back to an opaque ByteString, or picked the default binary encoding id of a similarly named type, the server sees a type it did not expect.
  • Enumeration written as a string or as the wrong integer typeEnumerations are transmitted as Int32. Sending the enumeration's symbolic name as a String, or sending a UInt32, mismatches. Some SDKs expose a friendly enum wrapper that encodes correctly and some do not, so the same logical write succeeds in one stack and fails in another.
  • Subtype written where the exact type is requiredA node declared as DataType Number or BaseDataType may accept a subtype, but a node declared as Double will not accept a Float unless the server implements subtype coercion. Servers differ here, which is why a write that works against one vendor fails against another with identical client code.

How to fix it

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

  1. Read the node's DataType, ValueRank and ArrayDimensions attributesDo not assume from the DisplayName or from what the value looks like. Read the DataType, ValueRank and ArrayDimensions attributes on the target node. DataType comes back as a NodeId; resolve it against the NamespaceArray so you know whether it is a namespace 0 built-in type or a vendor type.
  2. Read the current value and inspect the Variant type it comes back asA Read returns a DataValue whose Variant carries the server's own idea of the type. Mirroring exactly that built-in type on the write side removes the guesswork. In UaExpert the Data Type field in the Attributes pane shows both the DataType node and the encoded type of the value.
  3. Construct the Variant with an explicit type, not an inferred oneEvery SDK has a way to state the built-in type: an explicit Variant constructor in C#, ua.Variant with a VariantType in asyncua, a DataType member in node-opcua, UA_Variant_setScalar with the matching UA_TYPES entry in open62541. Inferred typing from a language integer or float is what produces the mismatch.
  4. Match rank before matching element typeIf ValueRank is 1, wrap the payload as an array even when it has one element, and check ArrayDimensions for a fixed length. If ValueRank is -1, unwrap. A rank error and an element type error produce the same status code, so fix rank first and retest before touching the element type.
  5. For structures, prove the encoding path worksRead the node first. If the value comes back as an undecoded ExtensionObject, your client did not load the type definition and any write you build will be wrong. Load the server's DataTypeDefinition, or its legacy type dictionary, before attempting to write.
  6. Write one item at a time while diagnosingWrite returns a per-item StatusCode array. Batching hides which item failed and encourages retrying the whole set. Isolate the failing item, fix it, then re-batch.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UaExpertThe Data Access View and the Attributes pane both show the node's DataType and ValueRank. Writing from the Attributes pane lets you pick the type explicitly, which is the fastest way to prove whether the problem is your client or the node definition.
asyncua (Python)node.write_value(x) infers the Variant type from the Python object, which is where most mismatches start. Use node.write_value(ua.DataValue(ua.Variant(x, ua.VariantType.Int16))) once you know the declared type, or read the node's DataType and derive the variant type from it.
node-opcuawriteValue requires dataType in the Variant. Passing DataType.Double to an Int16 node is rejected server-side. The DataType and VariantArrayType settings are the two knobs; getting arrayType wrong on a ValueRank 1 node is a frequent trap.
UA-.NETStandard (C#)A C# int becomes Int32 in a Variant. For an Int16 node use new Variant((short)value). For arrays, pass a typed array rather than a boxed object, and check that WriteValue.IndexRange is left null when you intend to replace the whole array.
open62541 (C)UA_Variant_setScalar with the wrong UA_TYPES index is a silent client-side error that surfaces as BadTypeMismatch on the wire. Read the node's DataType attribute and map it to the matching UA_TYPES entry before writing.
Siemens S7-1500Server tag types follow the PLC declaration exactly. An Int in the PLC is 16-bit, a DInt is 32-bit, and a Word is unsigned 16-bit. Writing from a high-level client that defaults to 32-bit integers fails against every Int tag until the width is set explicitly.

What it looks like in the log

Write to ns=3;s=Machine.Speed returned BadTypeMismatch (declared DataType Int16, supplied Int32)
ServiceFault: BadTypeMismatch - value rank mismatch, node ValueRank=1, supplied scalar
Failed to encode value for node: expected ExtensionObject with encoding id, got ByteString

Confirm the fix

Write the corrected value, then read the node back and compare both the value and the Variant's built-in type against what you sent. If the read-back type differs from the write type, the server coerced it and the next SDK or server version may not.

Stop it happening again

Generate client-side type bindings from the server's NodeSet2 export rather than hand-writing them, and cache DataType, ValueRank and ArrayDimensions at connect time alongside the resolved NodeId. Re-read them after any PLC download, since a tag width change is invisible to the client otherwise.

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