C# / .NET · recipe

Connect to an OPC UA server in C#

Build an ApplicationConfiguration, select an endpoint, then create a session. The configuration is not boilerplate you can skip: it holds your certificate stores, and a wrong path there is the usual cause of a first-connection failure.

StackOPCFoundation/UA-.NETStandard
Version1.5.378.156 stable, 2.0.0-preview.2

The code

using Opc.Ua;
using Opc.Ua.Client;
using Opc.Ua.Configuration;

// Minimal ApplicationConfiguration. In a real project this lives in a .Config.xml file.
static async Task<ApplicationConfiguration> BuildConfigAsync()
{
    var config = new ApplicationConfiguration
    {
        ApplicationName = "MyOpcUaClient",
        ApplicationUri  = "urn:example:my-opcua-client",   // must match the certificate SAN
        ApplicationType = ApplicationType.Client,
        SecurityConfiguration = new SecurityConfiguration
        {
            ApplicationCertificate = new CertificateIdentifier
            {
                StoreType = "Directory",
                StorePath = "./pki/own",              // persist this in a container
                SubjectName = "CN=MyOpcUaClient",
            },
            TrustedPeerCertificates   = new CertificateTrustList { StoreType = "Directory", StorePath = "./pki/trusted" },
            TrustedIssuerCertificates = new CertificateTrustList { StoreType = "Directory", StorePath = "./pki/issuer" },
            RejectedCertificateStore  = new CertificateTrustList { StoreType = "Directory", StorePath = "./pki/rejected" },
            AutoAcceptUntrustedCertificates = false,   // never true in production
        },
        TransportConfigurations = new TransportConfigurationCollection(),
        ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 },
    };
    await config.Validate(ApplicationType.Client);
    return config;
}

static async Task Main()
{
    var config = await BuildConfigAsync();

    // no security for the first diagnostic connection
    var endpoint = CoreClientUtils.SelectEndpoint(config, "opc.tcp://opcua.umati.app:4840", useSecurity: false);
    var configured = new ConfiguredEndpoint(null, endpoint, EndpointConfiguration.Create(config));

    using var session = await Session.Create(
        config, configured, updateBeforeConnect: false,
        sessionName: "MyOpcUaClient", sessionTimeout: 60000,
        identity: new UserIdentity(new AnonymousIdentityToken()), preferredLocales: null);

    Console.WriteLine($"connected: {session.Connected}");
    Console.WriteLine($"endpoint : {session.ConfiguredEndpoint.EndpointUrl}");
    foreach (var (uri, i) in session.NamespaceUris.ToArray().Select((u, i) => (u, i)))
        Console.WriteLine($"  ns={i}  {uri}");
}

What it prints

connected: True
endpoint : opc.tcp://opcua.umati.app:4840
  ns=0  http://opcfoundation.org/UA/
  ns=1  urn:umati:sample-server
  ns=2  http://opcfoundation.org/UA/DI/
  ns=3  http://opcfoundation.org/UA/Machinery/

Notes

  • The ApplicationUri in the configuration must match the URI entry in your certificate's SAN exactly. Mismatches here produce certificate errors that look like network errors.
  • CoreClientUtils.SelectEndpoint picks the strongest endpoint matching your useSecurity flag. Pass false first to prove reachability, then true.
  • Dispose the session. The using statement above does it; a leaked session holds server resources until its timeout expires.
  • In production, load the configuration from a .Config.xml file rather than building it in code: it is what the tooling and the CTT expect.

What breaks first

The first secure connection is refused after the unsecured one worked BadCertificateUntrusted
Your certificate is in the server's rejected store. Move it to trusted, and copy the server's certificate into ./pki/trusted on your side.

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.

Free download
OPC UA Troubleshooting & Integration Checklist
The field-tested checklist engineers use to diagnose certificates, ports and namespace problems fast, plus a Python (asyncua) client template.
Get the free checklist →
Free, no course, no login