How Do OPC UA Call Methods Resolve Object and Method IDs?

Stefan Weidner8 min read
OPC / OPC UAOther ManufacturerTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

After the fix, the client can call the TrustList object without browsing every instance-level Method: use i=11585 for the inherited FileType::Read, or use the instance Method i=12652. Do not use i=12532; that NodeId does not exist in the NodeSet described here.

Where does the Call request stop?

Follow the packet from the client to the target Method. The client sends a Call request through the configured OPC UA endpoint and session. Each operation contains two identifiers: objectId supplies the invocation context, while methodId identifies the Method declaration the client wants to invoke. The server must resolve that pair before executing application logic.

Path element Reading to take Pass condition Next check
Physical and network path Connection state at the configured server address and port The endpoint is reachable Check the OPC UA session
Session Active session and identity used for the Call The session remains active and the server receives the request Inspect the Call operation
Call operation objectId and methodId Both identifiers refer to nodes participating in a permitted relationship Resolve the Method against the object context
Execution Operation result and output arguments The Method proceeds to completion and returns its result Verify behavior and permissions

Layer one first. If the endpoint is unreachable or the session drops, Method inheritance is not yet relevant. Read the active endpoint configuration for the address and port; no fixed network values are defined by these Method nodes. Once the server receives the Call and rejects a particular identifier pair, move to namespace resolution.

Does the methodId identify a real Method node?

Resolve methodId directly in the server's active address space. A Method must be the target of at least one HasComponent reference whose source is an Object or ObjectType. A numeric identifier printed in an old table or CSV is not callable merely because it resembles neighboring standard identifiers.

NodeId Meaning in this case Resolution result
i=11585 FileType::Read Existing type-level Method and relevant to the TrustList type hierarchy
i=12532 Supposed TrustListType::Read Does not exist in the applicable NodeSet; stop and correct the identifier
i=12652 DefaultApplicationGroup::TrustList::Read Existing Method component on the TrustList object

The first decision is therefore mechanical: browse or otherwise inspect the active address space and confirm that the NodeClass is Method. If lookup fails for i=12532, inheritance rules cannot make that nonexistent node valid. Select i=11585 or i=12652, then evaluate its relationship to the supplied object.

Is the Method attached directly to the object?

For an Object used as objectId, first look for a HasComponent reference from that Object to the requested Method. This is the direct instance branch. With the TrustList object as context, i=12652 follows that branch and is a valid candidate.

The wording in Part 3 describes the owning Object or ObjectType as the context supplied to Call. That does not restrict an Object invocation to only the instance Method node. Part 4 also permits a client to supply the Method NodeId exposed through the Object's TypeDefinition. This capability avoids forcing the client to browse a separate Method node on every object instance when the type already publishes a well-known Method NodeId.

Relationship found Meaning Action
Object HasComponent requested Method The Method is directly associated with the instance Continue to argument and permission checks
No direct relationship, but the effective TypeDefinition contains the Method The client used a type-level Method identifier with an instance context Continue through the type-resolution branch
Neither relationship exists The object and Method do not form a callable pair Correct one of the NodeIds; do not invoke by BrowseName alone

objectId is not a substitute for methodId. It tells the server which instance or type owns the operation context. The Method node supplies the callable declaration and its argument metadata.

Which Method survives TypeDefinition inheritance?

The TypeDefinition includes inherited components. When a subtype does not override a Method, the Method originally defined by a supertype remains part of the subtype's effective component set. A client can therefore use that well-known supertype Method NodeId when calling an instance of the subtype.

For the TrustList case, the effective TypeDefinition contains FileType::Read at i=11585. Calling that Method with the TrustList object as objectId is the intended type-level branch. The server executes it in the context of the supplied TrustList object; it does not operate on the FileType node as though the type were an instance.

An override changes the result. An overriding component on a subtype hides the inherited parent component in the effective TypeDefinition. If a real TrustListType::Read override existed, that subtype Method would be the effective component instead of the hidden FileType::Read. In the NodeSet at issue, i=12532 is not such an override because the node does not exist.

Type-hierarchy condition Method identifier to select Reason
Method inherited without override The Method NodeId from the type that originally defines it That component remains visible in the effective TypeDefinition
Subtype supplies an override The overriding Method NodeId The override hides the parent component
Candidate identifier is absent from the NodeSet Neither inherited nor overridden candidate A nonexistent node cannot participate in resolution

What changes when objectId is an ObjectType?

When objectId identifies an ObjectType, the operation has a type context rather than an instance context. The requested Method must be a component of that ObjectType's effective hierarchy: the ObjectType itself or a supertype must be the source of the applicable HasComponent relationship.

Treat the description of ObjectType-owned Methods as analogous to static methods only for understanding the absence of an instance. It does not permit arbitrary combinations of a type and any Method elsewhere in the namespace. Follow the reference path and the override rules.

  1. Confirm that objectId resolves to an ObjectType.
  2. Confirm that methodId resolves to a Method.
  3. Walk the ObjectType and supertype component hierarchy.
  4. Apply hiding: if a subtype component overrides the parent component, select the effective subtype Method.
  5. Reject a Method that has no qualifying component path from the requested ObjectType hierarchy.

An instance-only Method such as i=12652 is not automatically callable with an ObjectType as context. Its relationship must independently satisfy the ObjectType branch; its relationship from the TrustList object proves only the instance branch.

Which permissions apply after Method resolution?

RolePermissions belong to specific nodes, which creates a second decision after the server accepts more than one identifier for the same logical operation. The specifications discussed here required clarification on whether authorization follows the Method NodeId supplied by the client, the effective Method selected from the type hierarchy, or the instance Method associated with objectId. Clarification requests 0009879 and 0009880 cover Method resolution and RolePermissions respectively.

Do not infer permission equivalence from matching BrowseNames. Read RolePermissions on every candidate Method node and on the object context, then test the deployed server with identities representing the permitted and denied roles. The server's diagnostic or audit facilities must reveal which node was used for the access decision; consult the server documentation for the applicable diagnostic setting.

Test Reading Interpretation
Authorized identity, instance Method Result for objectId plus i=12652 Establishes behavior for the direct-object branch
Authorized identity, type Method Result for the same objectId plus i=11585 Establishes behavior for the inherited-type branch
Denied identity, both identifiers Operation results and server audit record Shows whether both paths enforce the intended policy

If these paths authorize differently, treat that as an interoperability and security issue in the deployed server configuration. Standardize the client on one validated Method identifier and align permissions on the nodes the server actually evaluates.

How should the client resolve and call Read?

  1. Connect to the configured endpoint and verify that the session remains active.
  2. Set objectId to the NodeId of DefaultApplicationGroup::TrustList, identified here as i=12642.
  3. Resolve each candidate methodId in the active namespace. Remove i=12532 because it does not exist.
  4. For a direct instance call, select i=12652 and confirm a HasComponent path from i=12642.
  5. For a reusable type-based call, select i=11585 and confirm that FileType::Read remains visible in the TrustList object's effective TypeDefinition hierarchy.
  6. Read the Method's input and output argument metadata. Build the request from that metadata rather than assuming that two Methods named Read have interchangeable signatures.
  7. Read the relevant RolePermissions and execute the same call with the identities required by the application's access policy.
  8. Record the exact objectId/methodId pair, returned operation result, outputs, and server-side diagnostic or audit entry.

A client that already knows the standard type-level Method can prefer i=11585 and avoid browsing every TrustList instance. Use i=12652 when the application deliberately targets the instance declaration. Server implementations should resolve the inherited type component in the context of i=12642 and apply override hiding before dispatch.

How do I verify both valid resolution paths?

Run two controlled calls against the same object and equivalent inputs: (objectId=i=12642, methodId=i=11585) and (objectId=i=12642, methodId=i=12652). Confirm that each reaches the intended Read operation, returns the documented output structure, and produces the expected object-side effect or data. Then submit i=12532 only as a negative test and confirm that processing stops at node lookup rather than dispatching another Method by name.

Repeat the positive calls under each application role. Compare operation results with the configured permissions and the server's diagnostic or audit record. A successful data result alone does not prove that the correct Method declaration or authorization node was selected.

FAQ

How do I call FileType Read on a TrustList object?

Use the TrustList Object NodeId i=12642 as objectId and FileType::Read at i=11585 as methodId. This works through the object's effective TypeDefinition when the inherited Method has not been overridden.

How do I call the Read Method attached directly to TrustList?

Use i=12642 as objectId and i=12652 as methodId. Confirm the direct HasComponent relationship before issuing the Call.

How do I handle OPC UA Method overrides?

Walk the TypeDefinition hierarchy and select the effective component. A subtype override hides the parent Method; without an override, use the Method NodeId from the type that originally defined it.

How do I apply RolePermissions to inherited Methods?

Read RolePermissions on the instance, type-level, and effective Method nodes, then test both permitted and denied identities. Clarification request 0009880 addresses which node governs when different valid identifiers reach the same logical operation.

How do I prove the OPC UA Call fix works?

Call i=12642 with i=11585 and i=12652, compare their results and audit records, then verify that i=12532 fails node lookup and never reaches Method execution.

Back to blog