BadBrowseDirectionInvalid
BadReferences
BadBrowseDirectionInvalid means the BrowseDirection value is not one of the defined ones: Forward, Inverse or Both. It is almost always an out-of-range integer from hand-built request code or a configuration field, not a server problem. Use the SDK's enum and default to Forward for ordinary traversal.
What you actually see
A Browse call fails immediately with this code for every node, including well-known nodes such as the Objects folder, while a Read on the same session works.
Why it happens
- Integer outside the defined valuesBrowseDirection has three defined values - Forward, Inverse and Both. A value read from a configuration file, a command-line argument or a generated enum mapping that produces a fourth value is rejected. Because the failure is per request rather than per node, every browse fails identically.
- Uninitialised field in a hand-built requestConstructing a BrowseDescription without setting the direction can leave whatever the surrounding memory or default constructor produced. In C this is a genuine hazard; in managed languages the default usually maps to Forward, which is why the bug appears mostly in hand-rolled native clients.
- Enum mismatch across a language or protocol boundaryA client that passes the direction through a REST API, a message queue or a wrapper layer can lose the mapping, particularly where one side is one-based and the other zero-based. The symptom appears only for requests that crossed the boundary.
- Direction taken from user input without validationA tool that lets an operator or a script choose the direction as a number, or as a string mapped by index, will pass whatever is supplied. Validating against the three names at the point of entry removes the class of failure.
- Value confused with another enum in the same requestA BrowseDescription carries a direction, a NodeClass mask and a result mask, all integers. Assigning the mask value to the direction field, or vice versa, produces an out-of-range direction and a request that fails on the first field checked.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Use the SDK's named enumPass the library's BrowseDirection constant rather than an integer. This removes the possibility of an out-of-range value at compile time in typed languages and makes the code readable at the same time.
- Default to Forward for ordinary traversalForward follows references away from the starting node, which is what you want when walking a hierarchy downward. Use Inverse to find parents, and Both only when you genuinely need both directions, since it returns considerably more references.
- Initialise every field of a hand-built BrowseDescriptionSet NodeId, BrowseDirection, ReferenceTypeId, IncludeSubtypes, NodeClassMask and ResultMask explicitly. Zero-initialise the structure first in C. An uninitialised field in this structure produces failures that look like server misbehaviour.
- Validate any direction that came from outside your codeWhere the direction comes from configuration, a command line or an API call, accept the three names and map them yourself. Reject anything else with a clear message rather than passing it through to the server.
- Check you have not swapped fieldsLog the whole BrowseDescription before sending. Seeing a direction of 63 or a NodeClassMask of 1 immediately identifies a field swap, which is otherwise a slow bug to find by reading code.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| open62541 (C) | You build UA_BrowseDescription directly, so use UA_BROWSEDIRECTION_FORWARD and friends and zero-initialise the structure with the library's init helper before setting fields. |
| UA-.NETStandard (C#) | BrowseDirection is a typed enum on BrowseDescription, so an invalid value can only come from an explicit cast. If you are seeing this code, look for a cast from an integer in configuration handling. |
| node-opcua | BrowseDirection is exported by the library and accepted by name in browse descriptions. Passing a raw number is what produces this, particularly in code driven by a JSON configuration. |
| asyncua (Python) | ua.BrowseDirection.Forward is the value to use. The high-level get_children and get_references helpers set it for you, so this code generally means hand-built BrowseDescription objects. |
| Eclipse Milo (Java) | BrowseDirection is an enum with a defined numeric mapping, and the browse builder takes it directly. Errors here come from deserialising a configuration value into the enum by ordinal. |
| UaExpert | The browse behaviour is fixed by the tool, so if UaExpert can browse a node your client cannot, the request construction in your client is at fault rather than the server. |
What it looks like in the log
Browse failed: BadBrowseDirectionInvalid (browseDirection=7)
BrowseDescription: nodeId=ns=0;i=85 direction=63 nodeClassMask=1
Rejecting configured browse direction 'down'; expected Forward, Inverse or Both
Confirm the fix
Re-issue the browse with the named enum and confirm references are returned for a known node such as the Objects folder, then confirm your traversal reaches the depth you expect rather than stopping early.
Stop it happening again
Use named enums throughout, validate any enum value that crosses a configuration or API boundary, initialise browse descriptions fully in native code, and log the full request when a browse fails so a field swap is immediately visible.
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.