Every node in an OPC UA address space — every variable, object, method, and data type — has a unique address called a NodeId. When you read a tag value, browse the address space, or call a method, you are using a NodeId.
NodeIds are the OPC UA equivalent of register addresses in Modbus or class/instance/attribute paths in CIP. But NodeIds are more flexible: they can be numeric, strings, GUIDs, or arbitrary binary data — and they live inside namespaces that prevent collisions between vendors and standards.
This guide covers how NodeIds are structured, what each part means, the four identifier types, how to write them in standard notation, and the well-known NodeIds you should know.
Table of Contents
1. What Is a NodeId
A NodeId is the unique address of a node in the OPC UA address space. Every operation in OPC UA uses NodeIds to identify what data to read, write, or browse:
- Read —
Read NodeId ns=2;s=Tank.Level.Value - Write —
Write 75.4 to NodeId ns=2;s=Tank.Level.Setpoint - Browse —
Browse children of NodeId ns=0;i=85(the Objects folder) - CallMethod —
Call method NodeId ns=2;s=Pump.Start
NodeIds are server-defined. The server decides what NodeIds to assign and the client must use those exact NodeIds to access data.
2. The Three Parts of a NodeId
Every NodeId has three components:
| Part | Type | Description |
|---|---|---|
| Namespace Index | UInt16 (0–65535) | Identifies which namespace the identifier belongs to |
| Identifier Type | Enum | Specifies whether the identifier is Numeric, String, GUID, or Opaque |
| Identifier | Varies by type | The actual identifier value |
Together these three parts form a unique address. Two nodes can have the same identifier value if they are in different namespaces — the namespace index keeps them separate.
3. The Namespace Index
The namespace index is a 16-bit unsigned integer (UInt16) that maps to a namespace URI. The URI is the actual unique name of the namespace; the index is just a shortcut for efficient transmission.
How Namespace Index Maps to URI
Every OPC UA server has a NamespaceArray — a list of namespace URIs. The index of each URI in this array is the namespace index used in NodeIds.
| Namespace Index | Namespace URI | Description |
|---|---|---|
| 0 | http://opcfoundation.org/UA/ | OPC Foundation standard nodes (always at index 0) |
| 1 | Server’s application URI (e.g., urn:MyServer) | Server’s own custom nodes |
| 2 | Vendor-defined or standard namespace (e.g., urn:siemens.com:plc) | Vendor-specific or companion specification |
| 3+ | Additional namespaces | Companion specs, custom namespaces |
Why Namespace Index Can Change
The namespace index for a URI is server-specific and not guaranteed to stay the same. If the server adds a new namespace or reconfigures its URIs, indexes can shift. Clients should:
- Read the server’s NamespaceArray after connecting
- Find the URI they need
- Use the current index for that URI
For long-term references, clients should store the namespace URI (not the index) and look up the current index each connection.
4. The Four NodeId Identifier Types
The OPC UA standard defines four identifier types:
| Type Code | Name | Data Type | Example |
|---|---|---|---|
| 0 | Numeric | UInt32 | 2253 |
| 1 | String | String (UTF-8, max 4096 chars) | "Tank.Level.Value" |
| 2 | GUID | 16-byte GUID | 09087e75-8e5e-499b-954f-f2a9603db28a |
| 3 | Opaque | ByteString (max 4096 bytes) | 0xAB12CD34... |
Each type serves a different purpose. The choice affects performance, scalability, and ease of debugging.
5. Numeric NodeIds
Identifier Type: 0 Data Type: UInt32 (0 to 4,294,967,295)
Numeric NodeIds are the most efficient — smallest in memory, fastest to transmit, fastest to look up.
When to Use Numeric NodeIds
- Static, predefined nodes — nodes defined by standards or that won’t change (OPC Foundation standard nodes use numeric)
- Performance-critical applications — high-throughput servers
- Small embedded servers — limited memory, simple lookup
Examples
| NodeId | Description |
|---|---|
ns=0;i=2253 | Server object (standard) |
ns=0;i=85 | Objects folder (standard) |
ns=2;i=1001 | Custom variable in namespace 2 |
Encoding Optimization
OPC UA’s binary encoding has three optimized forms for small numeric NodeIds:
| Form | Used When | Bytes |
|---|---|---|
| Two-byte encoded | Namespace index = 0, identifier ≤ 255 | 2 bytes |
| Four-byte encoded | Namespace index ≤ 255, identifier ≤ 65535 | 4 bytes |
| Standard numeric | All other numeric NodeIds | 7 bytes |
This optimization is invisible to the user but significantly reduces bandwidth for OPC Foundation standard nodes.
6. String NodeIds
Identifier Type: 1 Data Type: UTF-8 String (max 4096 characters, case-sensitive)
String NodeIds use human-readable names like "Boiler.Temperature.Value" or "Plant1.Line2.Motor3.Speed".
When to Use String NodeIds
- Vendor implementations exposing PLC tag names — Kepware, Siemens OPC UA Server typically expose PLC tags as string NodeIds
- Hierarchical/dotted naming — when the structure is human-meaningful
- Easy debugging — engineers can read and write string NodeIds directly
- Dynamic address spaces — where nodes are created based on configuration
Examples
| NodeId | Description |
|---|---|
ns=2;s=Tank.Level.Value | Tank level variable |
ns=3;s=Plant1.Line2.Motor3.Speed | Hierarchical tag |
ns=4;s=DB1.STAT_CMD_PUMP_RUN | Siemens PLC tag |
Important: Case-Sensitive
String NodeIds are case-sensitive. Tank.Level and tank.level are different NodeIds.
Vendor Examples
- KEPServerEX: uses string NodeIds with channel.device.tag format (
ns=2;s=Channel1.Device1.Tag1) - Siemens S7-1500 OPC UA Server: uses string NodeIds based on the tag name in TIA Portal
- Rockwell FactoryTalk Linx: uses string NodeIds matching Logix tag names
7. GUID NodeIds
Identifier Type: 2 Data Type: 16-byte GUID (Globally Unique Identifier)
GUID NodeIds are 128-bit unique identifiers that are statistically guaranteed to be unique across all systems.
When to Use GUID NodeIds
- System-wide tracking — when nodes need to be tracked across multiple OPC UA servers (e.g., a work order moving between systems)
- Cross-server references — when the same logical entity exists in multiple places
- Node identity persistence — when guaranteed uniqueness is required across deployments
Example
ns=2;g=09087e75-8e5e-499b-954f-f2a9603db28a
Tradeoff
GUIDs are 16 bytes — much larger than typical numeric (4 bytes) or short string NodeIds. They are slower to transmit and process. Use only when the global uniqueness is genuinely needed.
8. Opaque (ByteString) NodeIds
Identifier Type: 3 Data Type: ByteString (max 4096 bytes)
Opaque NodeIds are arbitrary byte sequences that the server defines internally. The client cannot interpret the bytes — it just stores and returns them.
When to Use Opaque NodeIds
- Internal server identifiers that should not be parsed by clients
- Hash-based identifiers — using a hash of internal data as the NodeId
- Encoded composite identifiers — packing multiple values into a single identifier
- Database-generated IDs — using internal database keys as NodeIds
Example (Base64-encoded ByteString)
ns=1;b=b3BlbjYyNTQxIQ==
The b= prefix indicates a base64-encoded ByteString.
Practical Use
Opaque NodeIds are rare in industrial applications. They are mainly used in advanced server implementations where the internal data structure is complex.
9. Standard NodeId String Notation
OPC UA defines a standard string notation for representing NodeIds. This format is used in configuration files, documentation, error messages, and SDK APIs.
Format
ns=<namespace_index>;<type_prefix>=<identifier>
Type Prefixes
| Prefix | Identifier Type | Example |
|---|---|---|
i= | Numeric | ns=0;i=2253 |
s= | String | ns=2;s=Tank.Level |
g= | GUID | ns=2;g=09087e75-8e5e-499b-954f-f2a9603db28a |
b= | ByteString (base64) | ns=1;b=b3BlbjYyNTQxIQ== |
Shortcuts
When the namespace index is 0, you can omit ns=0;:
| Full Form | Shortcut |
|---|---|
ns=0;i=85 | i=85 |
ns=0;i=2253 | i=2253 |
For namespace indexes other than 0, the ns= prefix is mandatory.
10. The Null NodeId
A null NodeId is a special NodeId that represents “no node.” The canonical null NodeId is:
ns=0;i=0
(Numeric type, namespace 0, identifier 0)
Where Null NodeIds Appear
- Service parameters — some OPC UA services interpret null NodeIds as “use the default” or “no filter”
- Optional references — when a reference points to nothing
- Browse continuation — when there are no more nodes to browse
A real node in the address space cannot have a null NodeId. Servers must reject nodes that try to use null as their identifier.
Other Null NodeIds
Each identifier type has its own null form:
| Type | Null Form |
|---|---|
| Numeric | ns=0;i=0 |
| String | ns=0;s= (empty string) |
| GUID | ns=0;g=00000000-0000-0000-0000-000000000000 |
| Opaque | ns=0;b= (empty ByteString) |
11. ExpandedNodeId — System-Wide Unique Identifiers
A regular NodeId is unique within a single server. An ExpandedNodeId is unique across multiple servers. It includes the full namespace URI instead of just the index.
ExpandedNodeId Structure
| Field | Description |
|---|---|
| Namespace URI | Full URI string (e.g., http://siemens.com/opcua/plc) |
| Server Index | UInt32 — index of the server in the ServerArray |
| Identifier Type | Numeric, String, GUID, or Opaque |
| Identifier | The identifier value |
When to Use ExpandedNodeIds
- Cross-server references — when a node references something on a different OPC UA server
- Aggregating servers — server-of-servers architectures
- Long-term storage — saving NodeIds in a database for later use, where the namespace index could change
ExpandedNodeIds appear in some OPC UA service responses and in certain reference targets. For typical client operations, you use regular NodeIds.
12. Well-Known NodeIds You Should Know
The OPC Foundation defines many standard NodeIds in namespace 0. These are the same on every OPC UA server.
Top-Level Folder NodeIds
| NodeId | Name | Description |
|---|---|---|
i=84 | RootFolder | Root of the address space |
i=85 | Objects | All real objects (variables, methods) — start browsing here |
i=86 | Types | Type definitions (object types, variable types, data types) |
i=87 | Views | Views of the address space |
i=2253 | Server | The server object — contains diagnostic info, status, capabilities |
Server Status NodeIds
| NodeId | Name | Description |
|---|---|---|
i=2256 | ServerStatus | Server status structure |
i=2257 | ServerStatus_StartTime | When the server started |
i=2258 | ServerStatus_CurrentTime | Current server time |
i=2259 | ServerStatus_State | Running, Failed, Suspended, Shutdown |
i=2255 | NamespaceArray | List of all namespaces |
Common Type NodeIds
| NodeId | Name | Description |
|---|---|---|
i=58 | BaseObjectType | Root of all object types |
i=62 | BaseVariableType | Root of all variable types |
i=63 | BaseDataVariableType | Standard variable type |
i=68 | PropertyType | Property type |
Reference Type NodeIds
| NodeId | Name | Description |
|---|---|---|
i=33 | HierarchicalReferences | Parent reference type for hierarchical relationships |
i=35 | Organizes | Folder organization |
i=47 | HasComponent | Parent has child as a component |
i=46 | HasProperty | Parent has child as a property |
i=40 | HasTypeDefinition | Variable instance to its type |
Quick Reference
When connecting to any OPC UA server with UaExpert or any client, start browsing at i=85 (Objects folder) to see all real instance data.
13. How to Find a NodeId in a Server
Method 1: Browse with UaExpert
- Connect to the OPC UA server
- In the Address Space panel, browse to the node you want
- Right-click → Properties → look at the NodeId field
Method 2: TranslateBrowsePathsToNodeIds
If you know the browse path (e.g., Objects → MyDevice → Temperature), use the TranslateBrowsePathsToNodeIds service to get the NodeId without manually browsing.
This is the recommended approach for persistent client code — store the browse path in your code, translate it to a NodeId at runtime. If the server’s NodeIds change between versions, your code still works.
Method 3: Read the NamespaceArray
To find the namespace index for a known URI:
- Read NodeId
i=2255(NamespaceArray) - Find your URI in the array
- The index in the array is the namespace index
python
# Example with python-opcua
from opcua import Client
client = Client("opc.tcp://localhost:4840")
client.connect()
ns_array = client.get_namespace_array()
my_index = ns_array.index("urn:my:custom:namespace")
14. Best Practices for Choosing NodeId Identifier Types
| Use Case | Recommended Type | Why |
|---|---|---|
| Standard OPC Foundation nodes | Numeric (i=) | Required by spec, efficient |
| PLC tag access | String (s=) | Matches PLC tag naming, easy to debug |
| High-volume / low-latency systems | Numeric (i=) | Fastest lookup and transmission |
| System-wide tracking (work orders, batches) | GUID (g=) | Globally unique across all systems |
| Internal server-only identifiers | Opaque (b=) | Hidden from clients |
| Hierarchical configuration | String (s=) | Reflects hierarchy in the name |
General Recommendations
- Use numeric NodeIds for static, predefined nodes — better performance
- Use string NodeIds when human readability matters — easier debugging
- Avoid GUIDs unless you genuinely need cross-system uniqueness — they are larger and slower
- Avoid opaque NodeIds unless you have a specific reason — they hide information from clients
- Never change a NodeId for an existing node — clients depend on stable NodeIds. Servers must keep NodeIds stable across restarts and reconfigurations.
15. NodeIds in Wireshark
Wireshark decodes NodeIds in OPC UA messages automatically.
Useful Display Filters
| Filter | What It Shows |
|---|---|
opcua | All OPC UA traffic |
opcua.namespaceindex == 2 | Operations on nodes in namespace 2 |
opcua.identifiernumeric == 85 | Operations on the Objects folder |
opcua.identifierstring contains "Temperature" | Operations on string NodeIds containing “Temperature” |
What a NodeId Looks Like in a Decoded Packet
OpcUa Binary Protocol
Service: ReadRequest
NodesToRead: Array
[0]:
NodeId
NamespaceIndex: 2
IdentifierType: STRING (1)
Identifier: "Tank.Level.Value"
AttributeId: Value
For more on Wireshark OPC UA analysis, see: Wireshark for OPC UA
Summary
A NodeId is the unique address of a node in an OPC UA address space. Every read, write, browse, or method call uses NodeIds.
The key things to remember:
- A NodeId has three parts: namespace index, identifier type, and identifier
- The namespace index (UInt16) maps to a namespace URI via the server’s NamespaceArray
- Namespace 0 is always reserved for OPC Foundation standard nodes
- There are four identifier types: Numeric, String, GUID, Opaque
- Numeric NodeIds are the fastest — used for standard OPC Foundation nodes and performance-critical applications
- String NodeIds are the most readable — used by most PLC OPC UA servers (Siemens, Kepware, Rockwell)
- GUID NodeIds are 128-bit and globally unique — use only when system-wide uniqueness is needed
- Opaque NodeIds are byte strings — rarely used outside specialized server implementations
- The standard notation is
ns=<index>;<type>=<value>—i=numeric,s=string,g=GUID,b=ByteString - Start browsing at
i=85(Objects folder) to find real data on any OPC UA server - Servers must keep NodeIds stable — clients depend on them not changing across restarts
