NodeId
In OPC UA, a NodeId is the unique address of a node inside a server's address space. It combines a namespace index with an identifier that is Numeric (i=), String (s=), GUID (g=) or Opaque ByteString (b=). Every Read, Write, Browse, Call and MonitoredItem request names its target by NodeId.
The two halves of a NodeId
A NodeId is a structure, not a string: it carries a NamespaceIndex (UInt16), an IdentifierType and the identifier value itself. The textual forms nsu=...;s=... and ns=2;i=1001 are display and configuration conventions defined for tooling, not the wire format. Only the pair (namespace, identifier) matters for equality, and both halves must match exactly. The default namespace index is 0, so i=2253 and ns=0;i=2253 refer to the same node.
Identifier types and what servers actually use
Numeric identifiers are compact and are what the OPC Foundation uses for all standard nodes. String identifiers dominate PLC and gateway servers because they can carry the underlying tag path, for example ns=3;s="Machine"."Motor1"."Speed" on a Siemens S7-1500 or ns=2;s=Channel1.Device1.Tag1 on KEPServerEX. GUID and Opaque identifiers appear in generated or database-backed address spaces. A server may mix all four.
ExpandedNodeId
An ExpandedNodeId adds the full NamespaceUri and a ServerIndex to a NodeId, so it can name a node in a server other than the one you are talking to, or name it without depending on that server's namespace table. Structures that cross server boundaries (aggregating servers, event fields, PubSub metadata) use ExpandedNodeId for exactly that reason. Persist this form, or a URI plus identifier pair, in configuration.
Well-known NodeIds worth memorising
In namespace 0, i=84 is the RootFolder, i=85 the ObjectsFolder, i=86 the TypesFolder, i=87 the ViewsFolder and i=2253 the Server object. Any browse of an unfamiliar server starts at i=84 or i=85, and the Server object is where NamespaceArray, ServerStatus and ServerCapabilities live. Standard identifiers are stable across specification versions, so they are safe to hardcode.
Reading and comparing NodeIds
Servers reject a syntactically broken NodeId with BadNodeIdInvalid and a syntactically valid one that has no node behind it with BadNodeIdUnknown. That distinction is the fastest triage you have: BadNodeIdInvalid means your string parsing or namespace index is malformed, BadNodeIdUnknown means the address space moved or the node was never there.
Example
The same node addressed four ways, plus the four identifier types
Identifier types
Numeric ns=0;i=2258 (Server_ServerStatus_CurrentTime)
String ns=3;s="Machine"."Motor1"."Speed" (typical S7-1500 tag)
GUID ns=4;g=09087e15-8e5a-4d33-b8a7-3a5f0b5c4e11
Opaque ns=5;b=SGVsbG8gV29ybGQ= (base64 ByteString)
Namespace-safe forms (no reliance on the index)
nsu=http://example.com/Machine/;s=Motor1.Speed
ExpandedNodeId: NamespaceUri=http://example.com/Machine/, Identifier=s=Motor1.Speed, ServerIndex=0
Defined in: Part 3 - Address Space Model defines the NodeId attribute; Part 6 - Mappings defines its encodings and the textual notation.
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.