BadAttributeIdInvalid
BadAttributes
BadAttributeIdInvalid means you asked for an attribute the node cannot have. Every node carries NodeId, NodeClass, BrowseName and DisplayName; the rest are class-specific. Reading Value on an Object, or EventNotifier on a Variable, fails here. Read the NodeClass attribute first and ask only for attributes that class defines.
What you actually see
A Read returns Good at the service level but one entry in the results array carries this status, usually the entry for a folder or an object that a generic loop treated like a tag.
Why it happens
- The attribute does not apply to that NodeClassValue and DataType belong to Variables and VariableTypes. EventNotifier belongs to Objects and Views. Executable and UserExecutable belong to Methods. IsAbstract belongs to type nodes. A generic client that reads Value on everything it finds while browsing will hit this on the first folder.
- A generic collector treated an Object as a tagTag discovery that walks the address space and reads Value on every node produces a stream of these. The correct filter is on NodeClass, using the NodeClassMask on Browse so only Variables come back in the first place.
- An optional attribute the server does not implementAttributes added in later versions - AccessLevelEx, RolePermissions, AccessRestrictions, DataTypeDefinition - may not be present on an older or cut-down server. A client that reads the full attribute set of every node needs to tolerate this rather than treat it as an error.
- A wrong numeric AttributeId in hand-built codeAttributeIds are numeric on the wire, and the normative list is the AttributeIds schema file shipped with the nodesets. Code that hardcodes a number, or that computes one, can address an attribute that does not exist at all.
- Confusion between an attribute and a propertyEURange, EngineeringUnits and similar are Properties - separate nodes reached through HasProperty - not attributes of the Variable. Asking for them as attributes fails; browsing for them as child nodes works.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Read NodeClass before anything elseNodeClass is present on every node. One Read of that attribute tells you which other attributes are legal, and it is cheap enough to batch alongside your real reads.
- Filter the browse instead of filtering the resultsSet NodeClassMask on the BrowseDescription so only the classes you care about are returned. This removes the problem at the source and makes the browse smaller at the same time.
- Check the attribute against the normative listThe AttributeIds schema file in the UA nodeset distribution is the authoritative list of attribute identifiers. Use your SDK's named constants rather than numbers, and consult that file when adding support for a newer attribute.
- Treat optional attributes as best-effortRead them in a separate request from the mandatory ones, and accept a Bad status per item without failing the whole operation. This matters most for diagnostics and modelling tools that read the full attribute set.
- Look for properties where you expected attributesIf you wanted engineering units, range or a display-formatting hint, browse the Variable for HasProperty children instead of asking for another attribute.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| UaExpert | The Attributes pane shows exactly the attributes the selected node exposes, greying out or omitting the rest. It is the fastest way to see which class you are actually looking at. |
| asyncua (Python) | node.read_node_class() then a class-dependent attribute read is the safe pattern. node.read_value() on an Object raises with this status, which is a useful assertion in discovery code. |
| node-opcua | AttributeIds is exported as a named enumeration - use it rather than numeric literals. Reads return a DataValue per item, so inspect statusCode per entry instead of assuming the whole call failed. |
| open62541 (C) | The UA_Client_readXAttribute helpers are typed per attribute, so calling readValueAttribute on an Object gives you this status directly and unambiguously. |
| opcua-commander | Shows attributes and references side by side in the terminal, which makes the class-dependent attribute set obvious while you are exploring an unfamiliar address space. |
| Ignition | Browsing a server into tags picks Variables automatically. Manually created OPC tags pointed at an Object NodeId produce this status on every scan instead of a configuration error. |
What it looks like in the log
Read result[3] = BadAttributeIdInvalid for nodeId ns=2;i=5001 (attribute Value)
Attribute EventNotifier is not supported for NodeClass Variable
Skipping optional attribute AccessLevelEx: not supported by this server
Confirm the fix
Re-run the same read with NodeClass-aware attribute selection and confirm every entry in the results array carries Good, with no per-item Bad statuses left.
Stop it happening again
Filter browses with NodeClassMask, use SDK attribute constants rather than numbers, and read optional attributes in a separate best-effort request so an older server does not break discovery.
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.