OPC UA Protocol
OPC UA Protocol
1. Overview
This document describes two independent operational modes for IoTDB's integration with the OPC UA protocol. Choose the mode based on your business scenario:
- Mode 1: Data Subscription Service (IoTDB as OPC UA Server): IoTDB starts an embedded OPC UA server to passively allow external clients (e.g., UAExpert) to connect and subscribe to its internal data. This is the traditional usage.
- Mode 2: Data Push (IoTDB as OPC UA Client): IoTDB acts as a client to actively synchronize data and metadata to one or more independently deployed external OPC UA servers.
Note: This mode is supported starting from V2.0.8.
Note: Modes are mutually exclusive
When the Pipe configuration specifies the node-urls parameter (Mode 2), IoTDB will not start the embedded OPC UA server (Mode 1). These two modes cannot be used simultaneously within the same Pipe.
2. Data Subscription
This mode supports users subscribing to data from IoTDB using the OPC UA protocol, with communication modes supporting both Client/Server and Pub/Sub.
Note: This feature does not involve collecting data from external OPC Servers into IoTDB.

2.1 OPC Service Startup
2.1.1 Syntax
Syntax for starting OPC UA protocol:
CREATE PIPE p1
WITH SOURCE (...)
WITH PROCESSOR (...)
WITH SINK ('sink' = 'opc-ua-sink',
'sink.opcua.tcp.port' = '12686',
'sink.opcua.https.port' = '8443',
'sink.user' = 'root',
'sink.password' = 'TimechoDB@2021', // Default password was 'root' before V2.0.6.x
'sink.opcua.security.dir' = '...'
)2.1.2 Parameters
| Parameter | Description | Value Range | Required | Default Value |
|---|---|---|---|---|
| sink | OPC UA SINK | String: opc-ua-sink | Required | |
| sink.opcua.model | OPC UA operational mode | String: client-server / pub-sub | Optional | client-server |
| sink.opcua.tcp.port | OPC UA TCP port | Integer: [0, 65536] | Optional | 12686 |
| sink.opcua.https.port | OPC UA HTTPS port | Integer: [0, 65536] | Optional | 8443 |
| sink.opcua.security.dir | OPC UA key and certificate directory | String: Path (supports absolute/relative paths) | Optional | 1. opc_security folder under IoTDB's DataNode conf directory /. 2. User home directory's iotdb_opc_security folder / if no IoTDB conf directory exists (e.g., when starting DataNode in IDEA) |
| opcua.security-policy | Security policy used for OPC UA connections (case-insensitive). Multiple policies can be configured and separated by commas. After configuring one policy, clients can only connect using that policy. Default implementation supports None and Basic256Sha256. Should be set to a non-None policy by default. None policy is only for debugging (convenient but insecure; not recommended for production). Note: Supported since V2.0.8, only for client-server mode. | String (security level increases):None,Basic128Rsa15,Basic256,Basic256Sha256,Aes128_Sha256_RsaOaep,Aes256_Sha256_RsaPss | Optional | Basic256Sha256,Aes128_Sha256_RsaOaep,Aes256_Sha256_RsaPss |
| sink.opcua.enable-anonymous-access | Whether OPC UA allows anonymous access | Boolean | Optional | true |
| sink.user | User (OPC UA allowed user) | String | Optional | root |
| sink.password | Password (OPC UA allowed password) | String | Optional | TimechoDB@2021 (Default was 'root' before V2.0.6.x) |
| opcua.with-quality | Whether OPC UA publishes data in value + quality mode. When enabled, system processes data as follows:1. Both value and quality present → Push directly to OPC UA Server.2. Only value present → Quality automatically filled as UNCERTAIN (default, configurable).3. Only quality present → Ignore write (no processing).4. Non-value/quality fields present → Ignore data and log warning (configurable log frequency to avoid high-frequency interference).5. Quality type restriction: Only boolean type supported (true = GOOD, false = BAD).Note: Supported since V2.0.8, only for client-server mode | Boolean | Optional | false |
| opcua.value-name | Effective when with-quality = true, specifies the name of the value point. Note: Supported since V2.0.8, only for client-server mode | String | Optional | value |
| opcua.quality-name | Effective when with-quality = true, specifies the name of the quality point. Note: Supported since V2.0.8, only for client-server mode | String | Optional | quality |
| opcua.default-quality | When no quality is provided, specify GOOD/UNCERTAIN/BAD via SQL parameter. Note: Supported since V2.0.8, only for client-server mode | String: GOOD/UNCERTAIN/BAD | Optional | UNCERTAIN |
| opcua.timeout-seconds | Client connection timeout in seconds (effective only when IoTDB acts as client). Note: Supported since V2.0.8, only for client-server mode | Long | Optional | 10L |
2.1.3 Example
CREATE PIPE p1
WITH SINK ('sink' = 'opc-ua-sink',
'sink.user' = 'root',
'sink.password' = 'TimechoDB@2021'); // Default password was 'root' before V2.0.6.x
START PIPE p1;2.1.4 Usage Restrictions
- Data must be written after protocol startup to establish connection. Only data written after connection can be subscribed.
- Recommended for single-node mode. In distributed mode, each IoTDB DataNode acts as an independent OPC Server; separate subscriptions are required for each.
2.2 Example of Two Communication Modes
2.2.1 Client/Server Mode
In this mode, IoTDB's stream processing engine establishes a connection with the OPC UA Server (Server) via OPC UA Sink. The OPC UA Server maintains data in its address space (Address Space), and IoTDB can request and retrieve this data. Other OPC UA clients (Clients) can also access the server's data.
- Features:
- OPC UA organizes device information received from Sink into folders under Objects folder in tree structure.
- Each point is recorded as a variable node with the latest value in the current database.
- OPC UA cannot delete data or change data type settings.
2.2.1.1 Preparation
- Example using UAExpert client: Download UAExpert client from https://www.unified-automation.com/downloads/opc-ua-clients.html
- Install UAExpert and configure certificate information.
2.2.1.2 Quick Start
- Start OPC UA service using SQL (detailed syntax see IoTDB OPC Server Syntax):
CREATE PIPE p1 WITH SINK ('sink'='opc-ua-sink');- Write some data:
INSERT INTO root.test.db(time, s2) VALUES(NOW(), 2);- Configure UAExpert to connect to IoTDB (password matches
sink.passwordconfigured above, e.g., root/TimechoDB@2021): - Trust the server certificate, then view written data under Objects folder on the left:
- Drag left nodes to the middle to display latest value:
2.2.2 Pub/Sub Mode
In this mode, IoTDB's stream processing engine sends data change events to the OPC UA Server (Server) via OPC UA Sink. These events are published to the server's message queue and managed via Event Nodes. Other OPC UA clients (Clients) can subscribe to these Event Nodes to receive notifications when data changes.
Features:
Each point is packaged as an Event Node (EventNode) by OPC UA.
Related fields and meanings:
Field Meaning Type (Milo) Example Time Timestamp DateTime 1698907326198 SourceName Full path of point String root.test.opc.sensor0 SourceNode Data type of point NodeId Int32 Message Data LocalizedText 3.0
- Events are sent only to currently subscribed clients. Unconnected clients ignore events.
- Deleted data cannot be pushed to clients.
2.2.2.1 Preparation
Code located in example/pipe-opc-ua-sink/src/main/java/org/apache/iotdb/opcua of iotdb-example package.
Contains:
- Main class (
ClientTest) - Client certificate logic (
IoTDBKeyStoreLoaderClient) - Client configuration and startup logic (
ClientExampleRunner) - Parent class for
ClientTest(ClientExample)
2.2.2.2 Quick Start
- Open IoTDB and write some data:
INSERT INTO root.a.b(time, c, d) VALUES(NOW(), 1, 2); // Auto-creates metadata- Create and start Pub/Sub mode OPC UA Sink:
CREATE PIPE p1 WITH SINK ('sink'='opc-ua-sink', 'sink.opcua.model'='pub-sub');
START PIPE p1;- Observe server creates OPC certificate directory under conf:
- Run Client to connect, but server rejects Client certificate:
- Enter server's
sink.opcua.security.dir→pki→rejecteddirectory, find Client's certificate: - Move Client's certificate (not copy) to
trusted/certsdirectory: - Reopen Client → server certificate rejected by Client:
- Enter client's
<java.io.tmpdir>/client/security→pki→rejected→ move server's certificate (not copy) totrusted: - Open Client → successful bidirectional trust, connection established.
- Write data to server → Client prints received data:
2.2.3 Notes
- Single-node vs Cluster: Recommend single-node (1C1D). In cluster with multiple DataNodes, data may be distributed across nodes, preventing full data subscription.
- No root certificate operations: No need to handle IoTDB's root security directory
iotdb-server.pfxor client security directoryexample-client.pfx. During bidirectional connection, root certificates are exchanged. New certificates are placed inrejecteddirectory; if intrusted/certs, they're trusted. - Recommended Java 17+: JDK 8 may have key size restrictions causing "Illegal key size" errors. For specific versions (e.g., jdk.1.8u151+), add
Security.setProperty("crypto.policy", "unlimited");inClientExampleRunner.createClient(), or replaceJDK/jre/lib/security/local_policy.jarandUS_export_policy.jarwith unlimited versions from https://www.oracle.com/java/technologies/javase-jce8-downloads.html. - Connection issues: If error is "Unknown host", modify
/etc/hostson IoTDB DataNode machine to add target machine's URL and hostname.
3. Data Push
In this mode, IoTDB acts as an OPC UA client via Pipe to actively push selected data (including quality code) to one or more external OPC UA servers. External servers automatically create directory trees and nodes based on IoTDB's metadata.

3.1 OPC Service Startup
3.1.1 Syntax
Syntax for starting OPC UA protocol:
CREATE PIPE p1
WITH SOURCE (...)
WITH PROCESSOR (...)
WITH SINK ('sink' = 'opc-ua-sink',
'opcua.node-url' = '127.0.0.1:12686',
'opcua.historizing' = 'true',
'opcua.with-quality' = 'true'
)3.1.2 Parameters
| Parameter | Description | Value Range | Required | Default Value |
|---|---|---|---|---|
| sink | OPC UA SINK | String: opc-ua-sink | Required | |
| opcua.node-url | Comma-separated OPC UA TCP ports. When specified, IoTDB does not start local server but sends data to configured OPC UA Server. | String | Optional | '' |
| opcua.historizing | When automatically creating directories and leaf nodes, whether to store historical data in new nodes. | Boolean | Optional | false |
| opcua.with-quality | Whether OPC UA publishes data in value + quality mode. When enabled, system processes data as follows:1. Both value and quality present → Push directly to OPC UA Server.2. Only value present → Quality automatically filled as UNCERTAIN (default, configurable).3. Only quality present → Ignore write (no processing).4. Non-value/quality fields present → Ignore data and log warning (configurable log frequency).5. Quality type restriction: Only boolean type supported (true = GOOD, false = BAD). | Boolean | Optional | false |
| opcua.value-name | Effective when with-quality = true, specifies the name of the value point. | String | Optional | value |
| opcua.quality-name | Effective when with-quality = true, specifies the name of the quality point. | String | Optional | quality |
| opcua.default-quality | When no quality is provided, specify GOOD/UNCERTAIN/BAD via SQL parameter. | String: GOOD/UNCERTAIN/BAD | Optional | UNCERTAIN |
| opcua.security-policy | OPC UA client security policy (case-insensitive), URL format: http://opcfoundation.org/UA/SecurityPolicy#, e.g., http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep | String (security level increases):None,Basic128Rsa15,Basic256,Basic256Sha256,Aes128_Sha256_RsaOaep,Aes256_Sha256_RsaPss | Optional | Basic256Sha256 |
| opcua.timeout-seconds | Client connection timeout in seconds (effective only when IoTDB acts as client) | Long | Optional | 10L |
Parameter Naming Note: All parameters support omitting
opcua.prefix (e.g.,node-urlsandopcua.node-urlsare equivalent).Support Note: All
opcua.parameters are supported starting from V2.0.8, and only forclient-servermode.
3.1.3 Example
CREATE PIPE p1
WITH SOURCE (...)
WITH PROCESSOR (...)
WITH SINK ('sink' = 'opc-ua-sink',
'node-urls' = '127.0.0.1:12686',
'historizing' = 'true',
'with-quality' = 'true'
)3.1.4 Usage Restrictions
- Current mode only supports
client-servermode and tree model data. - Do not configure multiple DataNodes on one machine to avoid port conflicts.
- Does not support
OBJECTtype data push. - When a time series is renamed, OPC UA Sink automatically deletes the old path and pushes data to the new path.
- Strongly recommended to use non-
Nonesecurity policy (e.g.,Basic256Sha256) with proper bidirectional certificate trust in production.
3.2 External OPC UA Server Project
IoTDB supports a standalone external Server project. This Server implements the same configuration as IoTDB's embedded Server but requires additional support for dynamically creating directories and leaf nodes based on IoTDB's metadata.
Configuration is injected via command-line args when starting the Server (no YAML/XML support). Parameter keys match IoTDB OPC Server configuration items, with dots (.) and hyphens (-) replaced by underscores (_).
Example:
./start-IoTDB-opc-server.sh -enable_anonymous_access true -u root -pw root -https_port 8443Where user and password can be abbreviated as -u and -p. All other parameter keys match configuration items. Note: userName is not a valid parameter key; only user is supported.
3.3 Scenario Example
Goal: Aggregate data from multiple sources to 3 external OPC Servers for unified monitoring center access.

- Preparation: Start external OPC UA Server (port 12686) on three servers (
ip1,ip2,ip3). - Configure Pipes: Create 3 Pipes in IoTDB, using
processororsourcepath patterns to filter data by region and push to corresponding Servers.-- Start IoTDB ./start-standalone.sh -- Start three OPC UA Servers (on ip1, ip2, ip3) ./start-IoTDB-external-opc-server.sh -enable-anonymous-access true -u root -pw root -- Create three Pipes ./start-cli.sh CREATE PIPE p1 WITH SOURCE (<ip1 credentials>) WITH PROCESSOR (...) WITH SINK ('sink' = 'opc-ua-sink', 'node-urls' = 'ip1:12686', 'historizing' = 'true', 'with-quality' = 'true' ); CREATE PIPE p2 WITH SOURCE (<ip2 credentials>) WITH PROCESSOR (...) WITH SINK ('sink' = 'opc-ua-sink', 'node-urls' = 'ip2:12686', 'historizing' = 'true', 'with-quality' = 'true' ); CREATE PIPE p3 WITH SOURCE (<ip3 credentials>) WITH PROCESSOR (...) WITH SINK ('sink' = 'opc-ua-sink', 'node-urls' = 'ip3:12686', 'historizing' = 'true', 'with-quality' = 'true' ); - Result: The monitoring center only needs to connect to
ip1,ip2, andip3to access the complete data view from all regions, with quality information attached.