Discover available OPC UA servers on the network using opcuaserverinfo
When to Use
- Finding available OPC UA servers on the local network
- Getting the discovery URL or endpoint information for a known server
- Querying server security policies and supported authentication types
- Troubleshooting empty discovery results (LDS issues, certificate trust)
- Setting up prerequisites for OPC UA server discovery
When NOT to Use
- Creating OPC UA client connections (use
opcua()directly) - Reading, writing, or subscribing to OPC UA node values
- Configuring OPC UA connection security (message security, certificates)
- Working with non-OPC UA protocols (Modbus, MQTT)
- Discovering OPC Classic servers (OPC DA, OPC HDA)
Workflow
1. Check prerequisites
Before calling opcuaserverinfo, ensure:
- The OPC UA Local Discovery Service (LDS) is installed and running
- The target server is registered with the LDS
- The server's certificate is trusted by the LDS certificate store at
C:\ProgramData\OPC Foundation\UA\pki\trusted\certs\
Warning: A pki\ folder may also exist under UA\Discovery\ — that is a
backward-compatibility fallback from older LDS deployments. The primary store
is UA\pki\. Always place certificates in UA\pki\trusted\certs\.
See references/lds-setup-and-troubleshooting.md for paths and setup details.
2. Discover servers
Preferred approach — LDS-based discovery (finds all registered servers):
serverInfo = opcuaserverinfo('localhost');
A single call to opcuaserverinfo with a hostname queries that host's LDS on
port 4840. The LDS returns information about ALL servers registered with it.
Do not scan IP ranges or iterate over hosts — the LDS aggregates this.
Alternative — direct endpoint discovery (when you know the server URL):
serverInfo = opcuaserverinfo('opc.tcp://myserver:53530/OPCUA/SimulationServer');
Use this when connecting to a specific known server that may not be registered with the LDS, or when the LDS is not available.
3. Inspect results
for k = 1:numel(serverInfo)
fprintf('Server: %s (port %d)\n', serverInfo(k).Hostname, serverInfo(k).Port);
fprintf(' Best security: %s / %s\n', ...
serverInfo(k).BestMessageSecurity, serverInfo(k).BestChannelSecurity);
fprintf(' Endpoints: %d available\n', numel(serverInfo(k).Endpoints));
end
4. Connect to a discovered server
uaClient = opcua(serverInfo(1));
connect(uaClient);
The opcua() function accepts a ServerInfo object directly — no need to
extract hostname and port manually.
Key Functions
| Function | Syntax | Purpose |
|---|---|---|
opcuaserverinfo |
opcuaserverinfo(hostname) |
Query LDS on a host for all registered servers |
opcuaserverinfo |
opcuaserverinfo(discoveryUrl) |
Query a specific discovery endpoint URL |
opcua |
opcua(serverInfoObj) |
Create client from ServerInfo object |
findDescription |
findDescription(serverInfo, text) |
Filter servers by description text |
findAuthentication |
findAuthentication(serverInfo, type) |
Filter servers by auth type |
There is no opcuaserverinfo(hostname, port) syntax. To specify a port,
use the discovery URL form: opcuaserverinfo('opc.tcp://hostname:port').
opc.ua.ServerInfo Properties
| Property | Type | Description |
|---|---|---|
Hostname |
char | Host name of the OPC UA server |
Port |
double | TCP port for connections |
Description |
char | Human-readable server description |
UserTokenTypes |
cell array | Supported auth types (e.g., {'Anonymous', 'Username', 'Certificate'}) |
BestMessageSecurity |
enum | Highest message security: SignAndEncrypt, Sign, or None |
BestChannelSecurity |
enum | Highest channel security policy |
Endpoints |
array | Array of opc.ua.EndpointDescription objects |
Note: opc.ua.ServerInfo has Description, not Name. The Name property
belongs to opc.ua.Client, not ServerInfo.
opc.ua.EndpointDescription Properties
| Property | Type | Description |
|---|---|---|
EndpointUrl |
char | Full endpoint URL for connection |
MessageSecurityMode |
enum | Security mode for this endpoint |
ChannelSecurityPolicy |
enum | Channel security policy for this endpoint |
UserAuthTypes |
cell array | Auth types supported on this endpoint |
Patterns
Discover all servers via LDS
serverInfo = opcuaserverinfo('localhost');
if isempty(serverInfo)
disp('No servers found. Check LDS prerequisites.');
else
disp(serverInfo);
end
Discover a specific server by URL
serverInfo = opcuaserverinfo('opc.tcp://myserver:53530/OPCUA/SimulationServer');
disp(serverInfo);
Filter servers by authentication type
serverInfo = opcuaserverinfo('localhost');
anonServers = findAuthentication(serverInfo, 'Anonymous');
certServers = findAuthentication(serverInfo, 'Certificate');
Pass discovery result to opcua() for connection
serverInfo = opcuaserverinfo('localhost');
uaClient = opcua(serverInfo(1));
connect(uaClient);
Common Mistakes
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
opcuaserverinfo(host, port) |
Two-argument syntax does not exist | opcuaserverinfo('opc.tcp://host:port') |
| Scanning subnet IPs in a loop | LDS already aggregates all registered servers | opcuaserverinfo('localhost') returns all servers |
Using serverInfo.Name |
Property does not exist on ServerInfo |
Use serverInfo.Description |
Using serverInfo.EndpointUrl |
Property belongs to opc.ua.Client, not ServerInfo |
Use serverInfo.Endpoints(k).EndpointUrl |
| Assuming empty result means LDS is down | Empty result can also mean no servers registered or cert not trusted | First run sc query UALDS to confirm LDS status, then check registration and trust |
Using UA\Discovery\pki\ as the cert store |
Discovery\pki\ is a backward-compatibility fallback (only has trusted\) — not the primary store |
The LDS primary cert store is at C:\ProgramData\OPC Foundation\UA\pki\ (has both trusted\ and rejected\) — check rejected\certs\ for untrusted certs, copy to trusted\certs\ to trust them |
| Not mentioning LDS prerequisites | Discovery returns empty without proper setup | Always check: LDS running, server registered, certificate trusted |
Conventions
- Always prefer LDS-based discovery (
opcuaserverinfo(hostname)) over direct endpoint queries when finding all servers on a network - Always mention the three LDS prerequisites when discussing discovery setup
- Use
serverInfo.Descriptionfor display — notName(which doesn't exist) - Pass the
ServerInfoobject directly toopcua()— don't extract hostname/port manually - When discovery returns empty, do NOT assume the LDS is down — first verify with
sc query UALDS, then check server registration, then certificate trust (in that order)
Copyright 2026 The MathWorks, Inc.