Skip to content

How-to guide

Configuration

Configure the server: application, certificate, server endpoints and network binding, data transfer limits, and XML configuration.

This content was machine translated and may contain errors. Read in German

How-to guide

Configuration ​

Configure the application ​

Types usedOpcServerOpcApplicationConfigurationOpcCertificateStoresOpcCertificateStoreInfo

All code snippets on this page configure the server in code, unless they work with the default configuration of the server. The OpcServer instance is the central place for configuring the server application. The server's Security property provides the security settings as an instance of the OpcServerSecurity class. The CertificateStores property provides the certificate store settings as an instance of the OpcCertificateStores class.

If the server should also be configurable through XML, load its configuration from an XML file. The section Configuration through an XML file shows how the file is structured. To load the settings:

Load the configuration file by the name of the configuration: The LoadServerConfig method looks for the file <Name>.Config.xml in the working directory of the application, in the following example Opc.UaFx.Server.Config.xml.

csharp
server.Configuration = OpcApplicationConfiguration.LoadServerConfig("Opc.UaFx.Server");
vbnet
server.Configuration = OpcApplicationConfiguration.LoadServerConfig("Opc.UaFx.Server")

Load the configuration file by the path to the XML file: If the file is missing or cannot be read, LoadServerConfig and LoadServerConfigFile do not throw an exception but return null. If you assign this value to the Configuration property, the server silently starts with its default configuration. Check the return value:

csharp
var configuration = OpcApplicationConfiguration.LoadServerConfigFile(
        "MyServerAppNameConfig.xml");
 
// The method returns a null reference in case the file could not be loaded.
if (configuration == null)
    throw new InvalidOperationException("The server configuration could not be loaded.");
 
server.Configuration = configuration;
vbnet
Dim configuration = OpcApplicationConfiguration.LoadServerConfigFile( _
        "MyServerAppNameConfig.xml")

'The method returns a null reference in case the file could not be loaded.
If configuration Is Nothing Then
    Throw New InvalidOperationException("The server configuration could not be loaded.")
End If

server.Configuration = configuration

You can configure the server application in the following ways, among others:

Configure the application (in code): If you set no ApplicationName, the server uses the value of the AssemblyTitle attribute, alternatively that of the AssemblyProduct attribute, and otherwise OPC Application. At startup, the server takes the ApplicationUri from the Subject Alternative Name of its application certificate and overrides a value set in code. It uses the value from the code only when it creates a new certificate:

csharp
// Default: Value of AssemblyTitleAttribute of entry assembly.
server.ApplicationName = "MyServerAppName";
 
// Default: A null reference to use the URI of the application certificate.
// The value is used to create a new application certificate.
server.ApplicationUri = new Uri("urn:localhost:MyServerAppName");
vbnet
'Default: Value of AssemblyTitleAttribute of entry assembly.
server.ApplicationName = "MyServerAppName"

'Default: A null reference to use the URI of the application certificate.
'The value is used to create a new application certificate.
server.ApplicationUri = New Uri("urn:localhost:MyServerAppName")

In XML (below the OpcApplicationConfiguration element):

xml
<ApplicationName>MyServerAppName</ApplicationName>
<ApplicationUri>urn:localhost:MyServerAppName</ApplicationUri>

Configure the certificate stores (in code): By default, the certificate stores are in the CertificateStores folder in the application directory. The application certificate is in CertificateStores\App, rejected certificates are in CertificateStores\Rejected, and trusted certificates and issuers are in CertificateStores\Trusted. If the application directory is not writable, the server uses %ProgramData%\OPC Foundation\CertificateStores or %AppData%\OPC Foundation\CertificateStores instead. The OpcCertificateStores.PathProbings property defines which paths the server checks and in which order:

csharp
// Default: ".\CertificateStores\App"
server.CertificateStores.ApplicationStore.Path
        = @"%LocalApplicationData%\MyServerAppName\App Certificates";
 
// Default: ".\CertificateStores\Rejected"
server.CertificateStores.RejectedStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Rejected Certificates";
 
// Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedIssuerStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Trusted Issuer Certificates";
 
// Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedPeerStore.Path
        = @"%LocalApplicationData%\MyServerAppName\Trusted Peer Certificates";
vbnet
'Default: ".\CertificateStores\App"
server.CertificateStores.ApplicationStore.Path _
        = "%LocalApplicationData%\MyServerAppName\App Certificates"

'Default: ".\CertificateStores\Rejected"
server.CertificateStores.RejectedStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Rejected Certificates"

'Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedIssuerStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Trusted Issuer Certificates"

'Default: ".\CertificateStores\Trusted"
server.CertificateStores.TrustedPeerStore.Path _
        = "%LocalApplicationData%\MyServerAppName\Trusted Peer Certificates"

In XML (below the OpcApplicationConfiguration element):

xml
<SecurityConfiguration>
  <ApplicationCertificate>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\App Certificates</StorePath>
    <SubjectName>MyServerAppName</SubjectName>
  </ApplicationCertificate>

  <RejectedCertificateStore>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Rejected Certificates</StorePath>
  </RejectedCertificateStore>

  <TrustedIssuerCertificates>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Trusted Issuer Certificates</StorePath>
  </TrustedIssuerCertificates>

  <TrustedPeerCertificates>
    <StoreType>Directory</StoreType>
    <StorePath>%LocalApplicationData%\MyServerAppName\CertificateStores\Trusted Peer Certificates</StorePath>
  </TrustedPeerCertificates>
</SecurityConfiguration>

Product information of the server: Clients see the manufacturer, product name, and version in the status information of the server (BuildInfo). The server determines them from the entry assembly of the application: the manufacturer from AssemblyCompany, the product name from AssemblyTitle, and the version from AssemblyVersion. If ApplicationName is set, the server uses this value as the product name instead. To retrieve the information, call GetInfo:

csharp
OpcServerInfo info = server.GetInfo();
 
Console.WriteLine("{0} {1} {2}", info.CompanyName, info.ProductName, info.ProductVersion);
Console.WriteLine("Product URI: {0}", info.ProductUri);
vbnet
Dim info As OpcServerInfo = server.GetInfo()

Console.WriteLine("{0} {1} {2}", info.CompanyName, info.ProductName, info.ProductVersion)
Console.WriteLine("Product URI: {0}", info.ProductUri)
csharp
[assembly: AssemblyCompany("Example Machines Ltd.")]
[assembly: AssemblyTitle("Example Machine Server")]
[assembly: AssemblyVersion("1.2.0.0")]
vbnet
<Assembly: AssemblyCompany("Example Machines Ltd.")>
<Assembly: AssemblyTitle("Example Machine Server")>
<Assembly: AssemblyVersion("1.2.0.0")>

If the information should not come from the assembly, for example to also provide a product URI, override the GetInfoCore method in a derived server class:

csharp
public class MachineServer : OpcServer
{
    public MachineServer()
        : base("opc.tcp://localhost:4840/")
    {
    }
 
    protected override OpcServerInfo GetInfoCore()
    {
        return new OpcServerInfo(
                companyName: "Example Machines Ltd.",
                productName: "Example Machine Server",
                productVersion: new Version(1, 2, 0, 0),
                buildDate: new DateTime(2026, 1, 15),
                productUri: new Uri("urn:example:machine-server"));
    }
}
vbnet
Public Class MachineServer
    Inherits OpcServer

    Public Sub New()
        MyBase.New("opc.tcp://localhost:4840/")
    End Sub

    Protected Overrides Function GetInfoCore() As OpcServerInfo
        Return New OpcServerInfo( _
                companyName:="Example Machines Ltd.", _
                productName:="Example Machine Server", _
                productVersion:=New Version(1, 2, 0, 0), _
                buildDate:=New DateTime(2026, 1, 15), _
                productUri:=New Uri("urn:example:machine-server"))
    End Function
End Class

Application certificate ​

Types usedOpcServerOpcCertificateManagerOpcCertificateSettingsOpcServerSecurityOpcCertificateStoresOpcCertificateStoreInfo

The OPC UA .NET SDK loads certificates of the types .der and .cer (public part only) as well as .pfx and .p12 (with private key). If the server should provide a secure endpoint, the certificate must have a private key. A secure endpoint uses the OpcSecurityMode Sign or SignAndEncrypt.

1. To load an existing certificate from any path:

csharp
var certificate = OpcCertificateManager.LoadCertificate("MyServerCertificate.pfx");
vbnet
Dim certificate = OpcCertificateManager.LoadCertificate("MyServerCertificate.pfx")

To load a password-protected certificate, pass the password:

csharp
var certificate = OpcCertificateManager.LoadCertificate(
        "MyServerCertificate.pfx",
        password: "password");
vbnet
Dim certificate = OpcCertificateManager.LoadCertificate( _
        "MyServerCertificate.pfx", _
        password:="password")

2. To create a new certificate in memory:

csharp
var certificate = OpcCertificateManager.CreateCertificate(server);
vbnet
certificate = OpcCertificateManager.CreateCertificate(server)

To set properties of the certificate, use the OpcCertificateSettings class. These include, for example, the validity in months (600 by default), the ApplicationUri, or the names of the domains under which the server is reachable. The Organization property adds the organization (O) to the subject of the certificate, unless you set a SubjectName of your own:

csharp
// Lifetime in months, default: 600.
var settings = new OpcCertificateSettings("MyServerAppName") {
    ApplicationUri = new Uri("urn:localhost:MyServerAppName"),
    Lifetime = 60
};
 
settings.DomainNames.Add("localhost");
 
var certificate = OpcCertificateManager.CreateCertificate(settings);
vbnet
'Lifetime in months, default: 600.
Dim settings = New OpcCertificateSettings("MyServerAppName") With { _
    .ApplicationUri = New Uri("urn:localhost:MyServerAppName"), _
    .Lifetime = 60 _
}

settings.DomainNames.Add("localhost")

Dim certificate = OpcCertificateManager.CreateCertificate(settings)

A certificate that the SDK creates for the server by itself names the manufacturer from the product information of the server as the organization. It also contains the fully qualified domain name of the machine if DNS resolves it.

3. To save the certificate to any path:

csharp
OpcCertificateManager.SaveCertificate("MyServerCertificate.pfx", certificate);
vbnet
OpcCertificateManager.SaveCertificate("MyServerCertificate.pfx", certificate)

4. Set the server certificate:

csharp
server.Certificate = certificate;
vbnet
server.Certificate = certificate

5. The certificate must be stored in the certificate store for application certificates (ApplicationStore):

csharp
if (!server.CertificateStores.ApplicationStore.Contains(certificate))
    server.CertificateStores.ApplicationStore.Add(certificate);
vbnet
If Not server.CertificateStores.ApplicationStore.Contains(certificate) Then
    server.CertificateStores.ApplicationStore.Add(certificate)
End If

6. If you set no certificate, the server looks in the ApplicationStore for a certificate whose name matches the ApplicationName. Before that, it raises the CertificateRequested event, through which the application can provide a certificate itself. If the server finds no certificate, by default it automatically creates and uses a new certificate. Up to version 2.58, this also applies to an invalid certificate. As of version 2.59, the server keeps an existing but invalid certificate and raises the CertificateRequested event with the reason (see Protect your own certificate). If that fails as well, the server uses a temporary certificate in memory. If the server should use only the specified certificate, turn off this feature. To do so, set the AutoCreateCertificate property to false:

csharp
server.CertificateStores.AutoCreateCertificate = false;
vbnet
server.CertificateStores.AutoCreateCertificate = False

The Secure servers page describes how the server manages user identities, validates client certificates, and secures its endpoints and network interfaces. It also explains how to harden the server for production.

Endpoints ​

Types usedOpcServerOpcServerSecurityOpcSecurityPolicyOpcSecurityModeOpcSecurityAlgorithm

The endpoints of the server result from the cross product of the base addresses in use and the security policies configured for endpoints. A base address consists of a supported pair of scheme and port plus the host (IP address or DNS name). For data exchange, you can define several schemes on different ports. The supported schemes are opc.tcp and https. The server rejects other schemes with an ArgumentException.

By default, the server uses no particular policy to provide a secure endpoint. As a result, there are exactly as many endpoints as base addresses. If a server defines exactly one base address, there is only one endpoint with this base address and the security policy with the mode None. With n different base addresses, there are likewise only n different endpoints with the same security policy. With only one particular security policy, there are still n endpoints, all with exactly this policy. With m different security policies (s1 to sm) and n different base addresses (b1 to bn), each pairing of policy and base address results in one endpoint: s1+b1, s1+b2 to s1+bn, then s2+b1 to s2+bn, and so on up to sm+bn.

Besides the mode for securing the communication (security mode), the security policy of an endpoint defines a security algorithm and a level. According to the OPC Foundation, the level is a relative measure of the security mechanisms an endpoint uses. By definition, an endpoint with a higher level is therefore more secure than an endpoint with a lower level. However, this is only a guideline that nobody checks or enforces. The SDK calculates the level from the mode and the algorithm (OpcSecurityPolicy.Level property).

For example, if a server uses two security policies, they could be defined as follows:

  • Security policy A: Level=0, Security-Mode=None, Security-Algorithm=None
  • Security policy B: Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256

In addition, there are, for example, three base addresses for different schemes:

  • Base address A: "https://mydomain.com/"
  • Base address B: "opc.tcp://192.168.0.123:4840/"
  • Base address C: "opc.tcp://192.168.0.123:12345/"

The cross product results in the following endpoint descriptions:

  • Endpoint 1: Address="https://mydomain.com/", Level=0, Security-Mode=None, Security-Algorithm=None
  • Endpoint 2: Address="https://mydomain.com/", Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256
  • Endpoint 3: Address="opc.tcp://192.168.0.123:4840/", Level=0, Security-Mode=None, Security-Algorithm=None
  • Endpoint 4: Address="opc.tcp://192.168.0.123:4840/", Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256
  • Endpoint 5: Address="opc.tcp://192.168.0.123:12345/", Level=0, Security-Mode=None, Security-Algorithm=None
  • Endpoint 6: Address="opc.tcp://192.168.0.123:12345/", Level=1, Security-Mode=Sign, Security-Algorithm=Basic256Sha256

You set the primary base address either in the constructor of the OpcServer class or through the Address property of an OpcServer instance. If you set none, the server uses the address opc.tcp://localhost:4840:

csharp
var server = new OpcServer("opc.tcp://localhost:4840/");
server.Address = new Uri("opc.tcp://localhost:4840/");
vbnet
Dim server As New OpcServer("opc.tcp://localhost:4840/")
server.Address = New Uri("opc.tcp://localhost:4840/")

If the server should support additional base addresses, manage them with the RegisterAddress and UnregisterAddress methods. The Addresses property returns all base addresses the server uses, that is, all registered ones. If the value of the Address property was not set before, it takes the first address you define with RegisterAddress.

Define two additional base addresses:

csharp
server.RegisterAddress("https://mydomain.com/");
server.RegisterAddress("opc.tcp://192.168.0.123:12345/");
vbnet
server.RegisterAddress("https://mydomain.com/")
server.RegisterAddress("opc.tcp://192.168.0.123:12345/")

Remove (unregister) two base addresses from the server, which also changes the primary base address:

csharp
server.UnregisterAddress("https://mydomain.com/");
 
// server.Address becomes: "opc.tcp://192.168.0.123:12345/"
server.UnregisterAddress("opc.tcp://localhost:4840/");
vbnet
server.UnregisterAddress("https://mydomain.com/")

'server.Address becomes: "opc.tcp://192.168.0.123:12345/"
server.UnregisterAddress("opc.tcp://localhost:4840/")

If you unregister all addresses of the Addresses property, the value of the Address property is not set either.

The following code defines a secure policy for the endpoints of the server. If you do not specify an algorithm (OpcSecurityAlgorithm.Auto), the SDK chooses Basic256Sha256 for Sign and SignAndEncrypt. Other current algorithms are, for example, Aes128_Sha256_RsaOaep or Aes256_Sha256_RsaPss. Basic256 and Basic128Rsa15 are considered deprecated:

csharp
server.Security.EndpointPolicies.Add(new OpcSecurityPolicy(
        OpcSecurityMode.Sign,
        OpcSecurityAlgorithm.Basic256Sha256));
vbnet
server.Security.EndpointPolicies.Add(New OpcSecurityPolicy( _
        OpcSecurityMode.Sign, _
        OpcSecurityAlgorithm.Basic256Sha256))

As soon as you define a specific security policy for endpoints, the default policy with the mode None no longer applies. This policy is not recommended for production. If the server should support it anyway, add it explicitly to the list of endpoint policies:

csharp
server.Security.EndpointPolicies.Add(new OpcSecurityPolicy(
	OpcSecurityMode.None, OpcSecurityAlgorithm.None));
vbnet
server.Security.EndpointPolicies.Add(New OpcSecurityPolicy(
	OpcSecurityMode.None, OpcSecurityAlgorithm.None))

Bind to network interfaces ​

Types usedOpcServerOpcServerBindingOpcAddressScope

The server's Binding property defines the network interfaces to which the server binds its ports. By default, the server binds to all IPv4 and IPv6 addresses (OpcAddressScope.IPvX). Through the Addresses property, you can restrict the binding to specific IP addresses. In addition, the server binds its ports exclusively by default (UseExclusiveAddress property), so that no second process can use the same port. Starting a second server on the same port then fails:

csharp
// Default: OpcAddressScope.IPvX (IPv4 and IPv6)
server.Binding.AddressScope = OpcAddressScope.IPv4;
 
// Default: empty (bind to all network interfaces of the address scope)
server.Binding.Addresses.Add(IPAddress.Parse("192.168.0.123"));
 
// Default: true (only one process can bind to the port)
server.Binding.UseExclusiveAddress = false;
vbnet
'Default: OpcAddressScope.IPvX (IPv4 and IPv6)
server.Binding.AddressScope = OpcAddressScope.IPv4

'Default: empty (bind to all network interfaces of the address scope)
server.Binding.Addresses.Add(IPAddress.Parse("192.168.0.123"))

'Default: True (only one process can bind to the port)
server.Binding.UseExclusiveAddress = False

Data transfer limits ​

Types usedOpcServerOpcTransportOpcOperationLimits

The server limits the size of the data it exchanges with its clients. If a value exceeds one of these limits, encoding or decoding fails, for example with the status BadEncodingLimitsExceeded. If you transfer large strings, arrays, or structures, raise the limits through the server's Transport property:

csharp
server.Transport.MaxStringLength = 1048576;      // Default: 65535
server.Transport.MaxByteStringLength = 10485760; // Default: 5242880
server.Transport.MaxArrayLength = 1000000;       // Default: 65535
server.Transport.MaxMessageSize = 20971520;      // Default: 10485760
vbnet
server.Transport.MaxStringLength = 1048576      'Default: 65535
server.Transport.MaxByteStringLength = 10485760 'Default: 5242880
server.Transport.MaxArrayLength = 1000000       'Default: 65535
server.Transport.MaxMessageSize = 20971520      'Default: 10485760

The values correspond to the entries below the TransportQuotas element of the XML configuration. The server tells clients through its operation limits how many nodes a client may read, write, or subscribe to per request. By default, it reports no limits. With the OperationLimits property, the server determines suitable limits based on the available system resources and reports them to its clients:

csharp
// Default: false (the server does not announce any operation limits)
server.OperationLimits.AutoDetermineLimits = true;
vbnet
'Default: False (the server does not announce any operation limits)
server.OperationLimits.AutoDetermineLimits = True

Configuration through an XML file ​

If the server should also be configurable through XML, load its configuration from an XML file. The XML file must have the following standard XML tree:

xml
<?xml version="1.0" encoding="utf-8" ?>
<OpcApplicationConfiguration xmlns="http://opcfoundation.org/UA/SDK/Configuration.xsd"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xmlns:ua="http://opcfoundation.org/UA/2008/02/Types.xsd">
</OpcApplicationConfiguration>

The settings from the previous sections follow below the OpcApplicationConfiguration element. You load the file in one of the following ways:

  • By the path to the XML file with the LoadServerConfigFile method. The file can have any name and be in any location.
  • By the name of the configuration with the LoadServerConfig method. The file must then be named <Name>.Config.xml (for example Opc.UaFx.Server.Config.xml) and be in the working directory of the application.

Both methods return null if the file is missing or cannot be read (see Configure the application). The SDK does not support configuration through the App.config of the application (configSections with a reference to the XML file).