Skip to content

Issue with Endpoint Handling in DiscoveryClient.getEndpoints() #1666

@Pustj

Description

@Pustj

Hi,

I have encountered an issue with the way the library handles endpoint URLs when using DiscoveryClient.getEndpoints(). Specifically, even when I pass an endpoint URL in the following format:

opc.tcp://<srvname>.example.com:<port>/

The library retrieves endpoints with this structure instead:

opc.tcp://<srvname>:<port>/

As a result, if the server relies on fully qualified domain names (FQDNs), such as <srvname>.example.com, the mismatch causes a java.net.UnknownHostException. This happens because the library seems to drop the domain component (e.g., .example.com) from the provided endpoint URL.
This behavior introduces issues in environments where multiple servers or services with similar hostnames (but different domains) are used, and explicit domain resolution is required.
Steps to reproduce:

  1. Provide an endpoint URL in the format opc.tcp://<srvname>.example.com:<port>/.
  2. Call DiscoveryClient.getEndpoints(endpointUrl).
  3. Observe that the returned endpoints are missing the domain, resulting in opc.tcp://<srvname>:<port>/.

Expected behavior: The discovered endpoints should retain the full structure of the provided endpointUrl, including the domain (e.g., .example.com), for accurate host resolution.

Temporary workaround: To mitigate the issue, I am manually replacing the endpoint URL in the returned EndpointDescription object, as follows:

// endpointUrl = opc.tcp://<srv name>.example.com:<port>/
List<EndpointDescription> endpoints =  DiscoveryClient.getEndpoints(endpointUrl).get();
EndpointDescription endpoint = endpoints.get(0);
EndpointDescription endpoint2 = new EndpointDescription(
        endpointUrl,                     // Updated endpoint URL
        endpoint.getServer(),
        endpoint.getServerCertificate(),
        endpoint.getSecurityMode(),
        endpoint.getSecurityPolicyUri(), 
        endpoint.getUserIdentityTokens(),
        endpoint.getTransportProfileUri(),
        endpoint.getSecurityLevel()
);

OpcUaClientConfig config = OpcUaClientConfig.builder()
        .setEndpoint(endpoint2)
        .build();

Consumer<OpcTcpClientTransportConfigBuilder> configureTransport = builder -> {
    ...
};

// Create and configure the OPC UA client
client = OpcUaClient.create(config, configureTransport);

While this workaround allows me to proceed, it is not ideal since it relies on manually constructing a new EndpointDescription object each time. This approach adds unnecessary complexity to the code and feels cumbersome for something that should be handled directly by the library.
I kindly ask for clarification about this behavior or guidance on any better way to ensure that the domain is preserved in the discovered endpoints.

Thank you in advance for your support!
Best regards

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions