Skip to main content

OPC UA Client

This page documents the client route (OPCUA)—the broker connects to a remote OPC UA server and reads or writes device data over MQTT. To expose MQTT topics to OPC UA clients instead (SCADA, UaExpert, PLCs connect to the broker), see OPC UA Server.
The OPCUA route enables communication with OPC UA servers, providing a standardized, cross-platform protocol for industrial automation. It supports multiple authentication modes, security policies, and both NodeId and BrowsePath addressing.
OPC UA is vendor-neutral and widely supported by modern industrial equipment. Use it when you need secure, standardized communication across different manufacturer’s devices.

Basic Syntax

DEFINE ROUTE OPCServer WITH TYPE OPCUA
    ADD OPCUA_CONFIG
        WITH ENDPOINT_URL "opc.tcp://192.168.1.100:4840"
        WITH AUTH_MODE 0
        WITH AUTO_ACCEPT_UNTRUSTED_CERTIFICATES "true"
    ADD MAPPING ProcessData
        WITH EVERY 1 SECOND
        ADD TAG Temperature
            WITH ADDRESS "ns=2;s=Channel1.Device1.Temperature"
            WITH DATA_TYPE "FLOAT"
            WITH SOURCE_TOPIC "opcua/temperature"

Connection Configuration

OPCUA_CONFIG Parameters

ENDPOINT_URL
string
required
OPC UA server endpoint URL (e.g., opc.tcp://localhost:4840).
AUTH_MODE
integer
Authentication mode:
  • 0 - Anonymous (no authentication)
  • 1 - Username/Password
  • 2 - Certificate
Default: 0.
USERNAME
string
Username for authentication (required if AUTH_MODE is 1).
PASSWORD
string
Password for authentication (required if AUTH_MODE is 1).
USE_SECURITY
boolean
Enable security mode. Default: false.
SECURITY_POLICY
integer
Security policy level:
  • 0 - None
  • 1 - Basic128Rsa15
  • 2 - Basic256
  • 3 - Basic256Sha256
  • 4 - Aes128_Sha256_RsaOaep
  • 5 - Aes256_Sha256_RsaPss
Default: 0.
MESSAGE_SECURITY
integer
Message security mode:
  • 0 - None
  • 1 - Sign
  • 2 - SignAndEncrypt
Default: 0.
PKI_DIR
string
Root directory for the four-folder PKI store (own, issuer, trusted, rejected). Defaults to the OPC Foundation layout under local application data. Set an explicit path—and mount it as a volume in Docker—so certificates persist across restarts. See Certificate Management.
CLIENT_CERT_PATH
string
Path to a PKCS#12 (.pfx) or PEM client certificate used when AUTH_MODE is 2. The broker loads it, adopts its application URI, and stores it under PKI_DIR/own. When omitted, a self-signed certificate is auto-generated on first connect.
CLIENT_KEY_PATH
string
Path to the private key PEM file when CLIENT_CERT_PATH points to a certificate-only PEM. Not needed for PKCS#12 bundles.
CLIENT_CERT_PASSWORD
string
Password for the PKCS#12 bundle or encrypted private key. Use GET SECRET—never hard-code passwords in route definitions.
AUTO_ACCEPT_UNTRUSTED_CERTIFICATES
boolean
Automatically accept untrusted server certificates. Default: false. For production, leave false and trust the server certificate explicitly—see Certificate Management.
SUPPRESS_NONCE_VALIDATION_ERRORS
boolean
Suppress nonce validation errors. Default: false.
TIMEOUT
integer
Connection timeout in milliseconds. Default: 90000.

Security Configuration

For development or trusted networks:
ADD OPCUA_CONFIG
    WITH ENDPOINT_URL "opc.tcp://192.168.1.100:4840"
    WITH AUTH_MODE 0
    WITH USE_SECURITY "false"
    WITH AUTO_ACCEPT_UNTRUSTED_CERTIFICATES "true"

Certificate Management

A secured OPC UA client connection requires two certificates that trust each other: the broker’s application instance certificate (channel security and, with AUTH_MODE 2, user identity) and the server’s certificate (must be in your trusted store). For server-side trust workflows, see OPC UA Server.
Like exchanging ID badges at a secure facility. Both sides must recognize each other’s badge before the door opens—moving a certificate from rejected to trusted is how you approve a new badge.

PKI directory layout

Both client and server routes store certificates in four folders under PKI_DIR:
FolderHoldsFile form
ownThis application’s certificate (own/certs) and private key (own/private)*.der + *.pfx
issuerTrusted CA / issuer certificates for chain validation*.der
trustedTrusted peer certificates—the server you accept goes here (trusted/certs)*.der
rejectedCertificates seen during a handshake but not yet trusted*.der

Where certificates live

When PKI_DIR is not set, it defaults to %LocalApplicationData%/OPC Foundation/pki:
OSDefault path
macOS~/Library/Application Support/OPC Foundation/pki
Linux$XDG_DATA_HOME/OPC Foundation/pki or ~/.local/share/OPC Foundation/pki
Windows%LOCALAPPDATA%\OPC Foundation\pki
Relocate the store to a path you control:
ADD OPCUA_CONFIG
    WITH ENDPOINT_URL "opc.tcp://server:4840"
    WITH PKI_DIR "/data/opcua/pki"
In Docker, the default PKI location is ephemeral—the broker regenerates its certificate on every restart and any server that trusted the previous one will reject the new one. Always set PKI_DIR to a mounted volume.

Inspecting and exporting certificates

Certificates are plain files you can inspect with openssl:
# The broker's own certificate and private key
ls "$PKI_DIR"/own/certs/*.der
ls "$PKI_DIR"/own/private/*.pfx

# Inspect subject, validity, and application URI SAN
openssl x509 -inform der -in "$PKI_DIR"/own/certs/<name>.der -noout -subject -dates -ext subjectAltName

# Export public cert for the server's trust list
openssl x509 -inform der -in "$PKI_DIR"/own/certs/<name>.der -out broker-client.pem
Give peers the public certificate (own/certs/*.der). The private key (own/private/*.pfx) never leaves the broker.

Auto-generated client certificate

With AUTH_MODE 2 and no CLIENT_CERT_PATH, the broker auto-generates a self-signed certificate (CN=CorefluxBroker_OpcUaClient, O=Coreflux) in PKI_DIR/own on first connect:
DEFINE ROUTE PlantClient WITH TYPE OPCUA
    ADD OPCUA_CONFIG
        WITH ENDPOINT_URL "opc.tcp://server:4840"
        WITH AUTH_MODE 2
        WITH USE_SECURITY true
        WITH SECURITY_POLICY 3
        WITH MESSAGE_SECURITY 2
        WITH PKI_DIR "/data/opcua/pki"
You still must (1) get this broker certificate trusted by the server and (2) trust the server’s certificate—see the workflows below.
An application instance certificate must carry an application URI in its Subject Alternative Name. The OPC UA stack matches certificates by that URI and rejects certificates without one.

Supply your own client certificate

Use a certificate from your PKI via CLIENT_CERT_PATH. Generate it with a mandatory URI SAN:
# Self-signed example—use your CA in production. The URI SAN is mandatory.
openssl req -x509 -newkey rsa:2048 -keyout client-key.pem -out client-cert.pem -days 825 -nodes \
  -subj "/CN=PlantClient/O=ACME" \
  -addext "subjectAltName=URI:urn:acme:opcua:plant-client" \
  -addext "keyUsage=digitalSignature,keyEncipherment,dataEncipherment,nonRepudiation" \
  -addext "extendedKeyUsage=clientAuth,serverAuth"

# Bundle into PKCS#12 (.pfx)
openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem \
  -out client.pfx -passout pass:CHANGEME -name plantclient

Trust the server’s certificate

Required when USE_SECURITY true and AUTO_ACCEPT_UNTRUSTED_CERTIFICATES false:
1

Deploy the route

The first handshake fails and the server’s certificate is written to PKI_DIR/rejected/certs.
2

Move to trusted

mv "$PKI_DIR"/rejected/certs/<server-cert>.der "$PKI_DIR"/trusted/certs/
3

Reconnect

The route reconnects automatically—the handshake now succeeds.
For testing only, skip this with WITH AUTO_ACCEPT_UNTRUSTED_CERTIFICATES true.

Get the broker trusted by the server

For AUTH_MODE 2, the server must trust the broker’s client certificate:
1

Export the broker certificate

openssl x509 -inform der -in "$PKI_DIR"/own/certs/<name>.der -out broker-client.pem
2

Add to the server's trust list

Import broker-client.pem (or the .der) into the server’s trusted certificate store—via its PKI trusted folder or vendor certificate manager.
3

Reconnect

The server now accepts the certificate identity.

Rotation and renewal

  • Auto-generated certificates — Delete files in PKI_DIR/own/certs and PKI_DIR/own/private, then reconnect; the broker regenerates a new self-signed certificate.
  • Supplied certificates — Replace the .pfx/PEM file, remove the old copy from PKI_DIR/own, and redeploy. Re-distribute the new public certificate to the server’s trust list before the old one expires.
  • Plan rotation before expiry—an expired application instance certificate fails the handshake.

Verify the connection

After mutual trust is configured, confirm the route connects:
-checkRouteConnection PlantClient
Publish that command to $SYS/Coreflux/Command. A response with "success": true means the certificate-authenticated session is established.

NodeId Addressing

OPC UA uses NodeIds to identify variables. The format is: ns=<namespace>;s=<identifier> or ns=<namespace>;i=<numeric_id>
FormatExampleDescription
String identifierns=2;s=Channel1.Device1.Tag1Most common, human-readable
Numeric identifierns=2;i=1234More efficient, used by some servers
GUID identifierns=2;g=12345678-1234-1234-1234-123456789012Globally unique identifiers

Finding NodeIds

Use an OPC UA browser tool (like UaExpert, Prosys OPC UA Browser, or similar) to explore the server’s address space and find the correct NodeIds.

BrowsePath Mode

For servers that support it, you can use symbolic paths instead of NodeIds:
USE_BROWSE_PATH
boolean
Enable BrowsePath mode - treat all TAG addresses as browse paths instead of NodeIds.
BROWSE_ROOT_PATH
string
Root path for browsing when USE_BROWSE_PATH is enabled. Default: Objects.

BrowsePath Example

ADD OPCUA_CONFIG
    WITH ENDPOINT_URL "opc.tcp://192.168.1.100:4840"
    WITH USE_BROWSE_PATH "true"
    WITH BROWSE_ROOT_PATH "Objects"
ADD MAPPING Tags
    WITH EVERY 1 SECOND
    ADD TAG Temperature
        WITH ADDRESS "Aliases/MyDevice/Temperature"
        WITH DATA_TYPE "FLOAT"
        WITH SOURCE_TOPIC "opcua/temperature"

Data Types

Data TypeOPC UA TypeDescription
BOOLEAN / BOOLBooleanTrue/False value
SBYTE / SINTSByteSigned 8-bit integer
BYTE / USINTByteUnsigned 8-bit integer
INT16 / INT / WORDInt1616-bit integer
UINT16 / UINTUInt16Unsigned 16-bit integer
INT32 / DINTInt32Signed 32-bit integer
UINT32 / UDINT / DWORDUInt32Unsigned 32-bit integer
INT64 / LINTInt64Signed 64-bit integer
UINT64 / ULINT / LWORDUInt64Unsigned 64-bit integer
FLOAT / FLOAT32 / REALFloat32-bit floating point
DOUBLE / FLOAT64 / LREALDouble64-bit floating point
CHARCharSingle character
WCHARWCharWide character
TIMETimeTime duration
DATEDateDate value
TODTimeOfDayTime of day
STRINGStringUnicode string (configurable STRING_SIZE)

TAG Configuration

Complete TAG Example

ADD TAG ProcessTemperature
    WITH ADDRESS "ns=2;s=Process.Temperature"
    WITH DATA_TYPE "FLOAT"
    WITH SOURCE_TOPIC "opcua/process/temperature"
    WITH SCALING 1
    WITH OFFSET 0
    WITH UNIT "°C"
    WITH DECIMAL_PLACES 2
    WITH MIN_VALUE -50
    WITH MAX_VALUE 500
    WITH DEADBAND 0.5
    WITH PUBLISH_MODE "JSON"
    WITH WRITABLE "true"
    WITH DESTINATION_TOPIC "opcua/process/temperature/set"
    WITH IS_ARRAY "false"
    WITH DESCRIPTION "Main process temperature sensor"

TAG Parameters

ADDRESS
string
required
OPC UA NodeId (e.g., ns=2;s=MyVariable or ns=2;i=1234) or BrowsePath if USE_BROWSE_PATH is enabled.
DATA_TYPE
string
required
OPC UA data type: BOOLEAN, BYTE, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, STRING.
IS_ARRAY
boolean
Indicates if the value is an array. Default: false.
SCALING
double
Multiplier for value transformation. Default: 1.0.
OFFSET
double
Offset added after scaling. Default: 0.0.
DECIMAL_PLACES
integer
Decimal places in output. Default: 2.
MIN_VALUE
double
Minimum allowed value.
MAX_VALUE
double
Maximum allowed value.
DEADBAND
double
Minimum change to trigger publish. Default: 0.0.
SOURCE_TOPIC
string
Topic where PLC values are published. Subscribe here to receive sensor data.
PUBLISH_MODE
string
Output format: VALUE_ONLY or JSON. Default: VALUE_ONLY.
UNIT
string
Engineering unit for documentation.
DESCRIPTION
string
Human-readable description.
WRITABLE
boolean
Allow writing to this node. Default: false.
DESTINATION_TOPIC
string
Topic to send write commands. Publish a value here to write it to the PLC.

Event-Based Operations

For on-demand OPC UA operations (not polling), use the EVENT syntax. Publish a message to SOURCE_TOPIC to trigger the operation; the route executes it and publishes the result to DESTINATION_TOPIC.

Supported Operations

OperationDescriptionQuery Parameters
READRead a node value on demandnode_id, data_type
WRITEWrite a value to a nodenode_id, data_type, value

Query Parameters

ParameterDescriptionExample
operationOperation type: READ or WRITEREAD
node_idOPC UA NodeId (string or numeric)ns=2;i=2, ns=2;s=Process.Temp
data_typeOPC UA data typeINT32, FLOAT, DOUBLE, STRING
valueValue to write (WRITE only)42, 23.5, "hello"

Read Example

Read a node value on demand:
ADD EVENT ReadOnDemand
    WITH SOURCE_TOPIC "opcua/commands/read"
    WITH DESTINATION_TOPIC "opcua/responses/read"
    WITH QUERY "{operation: READ, node_id: ns=2;i=2, data_type: INT32}"

Write Example

Write a FLOAT value to a node on demand:
ADD EVENT WriteSetpoint
    WITH SOURCE_TOPIC "opcua/commands/write"
    WITH DESTINATION_TOPIC "opcua/responses/write"
    WITH QUERY "{operation: WRITE, node_id: ns=2;s=Process.Setpoint, data_type: FLOAT, value: 75.0}"

Complete Examples

Simple OPC UA connection with anonymous access:
DEFINE ROUTE OPCServer WITH TYPE OPCUA
    ADD OPCUA_CONFIG
        WITH ENDPOINT_URL "opc.tcp://192.168.1.100:4840"
        WITH AUTH_MODE 0
        WITH AUTO_ACCEPT_UNTRUSTED_CERTIFICATES "true"
    ADD MAPPING ProcessData
        WITH EVERY 1 SECOND
        ADD TAG Temperature
            WITH ADDRESS "ns=2;s=Channel1.Device1.Temperature"
            WITH DATA_TYPE "FLOAT"
            WITH SOURCE_TOPIC "opcua/temperature"
            WITH UNIT "°C"
        ADD TAG Pressure
            WITH ADDRESS "ns=2;s=Channel1.Device1.Pressure"
            WITH DATA_TYPE "FLOAT"
            WITH SOURCE_TOPIC "opcua/pressure"
            WITH UNIT "bar"
        ADD TAG Status
            WITH ADDRESS "ns=2;s=Channel1.Device1.Status"
            WITH DATA_TYPE "INT32"
            WITH SOURCE_TOPIC "opcua/status"

Security Best Practices

Always enable security for production deployments:
WITH USE_SECURITY "true"
WITH SECURITY_POLICY 3  // Basic256Sha256
WITH MESSAGE_SECURITY 2  // SignAndEncrypt
In production, properly configure certificate trust:
WITH AUTO_ACCEPT_UNTRUSTED_CERTIFICATES false
Move server certificates from PKI_DIR/rejected/certs to PKI_DIR/trusted/certs during commissioning. See Certificate Management.
Prefer username/password or certificate authentication over anonymous:
WITH AUTH_MODE 1  // or '2' for certificate
WITH USERNAME "operator"
WITH PASSWORD "strong_password_here"

Troubleshooting

  • Verify endpoint URL is correct
  • Check firewall allows TCP port (usually 4840)
  • Ensure server is running and accessible
  • Try increasing TIMEOUT value
  • Verify security policy matches server configuration
  • Server certificate not trusted — Move it from PKI_DIR/rejected/certs to PKI_DIR/trusted/certs, or set AUTO_ACCEPT_UNTRUSTED_CERTIFICATES true for testing only
  • Supplied certificate ignored — Reissue with a subjectAltName=URI:... SAN; certificates without an application URI are rejected
  • Server rejects client certificate — Export the broker’s public cert from PKI_DIR/own/certs and add it to the server’s trust list
  • Certificate regenerates every restart — Set PKI_DIR to a persistent volume (especially in Docker)
  • BadCertificateUriInvalid — Regenerate the certificate or set a stable application URI in the SAN
  • Verify the file path is correct and readable by the broker
  • Check CLIENT_CERT_PASSWORD matches the PKCS#12 bundle or encrypted key
  • For a split PEM (certificate and key in separate files), set CLIENT_KEY_PATH
  • The broker log names the failing file—check it for the exact cause
  • Use OPC UA browser to verify correct NodeId
  • Check namespace index (ns=) is correct
  • Verify node exists in server’s address space
  • Try BrowsePath mode if NodeId is unclear
  • Verify username and password
  • Check user has appropriate permissions
  • Ensure AUTH_MODE matches server requirements
  • Verify DATA_TYPE matches server variable type
  • Check IS_ARRAY setting for array values
  • Verify SCALING and OFFSET calculations

Next Steps

OPC UA Server Route

Expose MQTT topics as OPC UA nodes for SCADA and OT clients.

ADS (Beckhoff)

Connect to TwinCAT systems.
Last modified on July 3, 2026