Timeouts and diagnostics
Timeouts in the SDK
Section titled “Timeouts in the SDK”The client option timeout_ms (1 to 300000 ms) applies to two things:
- Each network exchange of discovery, connecting, session activation and closing.
- Each request sent with
pdcomm_opcua_client_begin, whose response must arrive within that time.
It defaults to 10000 ms in C (pdcomm_opcua_client_options_init) and .NET (ClientOptions), and to 5000 ms in the Qt and MFC workers. The C example sets it with --timeout.
Connecting with 1000 ms to a server that accepts the connection but never answers gives this error after one second:
Error: discover failed (SDK status 5): OPC UA timeoutWhen a request exceeds the timeout, the next pdcomm_opcua_client_poll fails and the connection closes; later calls return PDCOMM_OPCUA_CLOSED. Release the handle and connect again. Publish requests are answered up to a publishing or keep-alive interval later, so with subscriptions, set the timeout longer than the keep-alive period.
If the server aborts one response (an abort chunk), only that request ends with PDCOMM_OPCUA_RUNTIME_ERROR and the connection stays open. The error text includes the StatusCode the server sent.
Timeouts in the simulator
Section titled “Timeouts in the simulator”The simulator client’s client.timeout_ms (100 to 60000 ms, default 5000) plays the same role. When a request exceeds it, the simulator closes the connection and returns:
{"error":"Timeout (client connection closed)","ok":false}You can reproduce a slow response with the Simulator.Delay method. Set the timeout to 1000 ms and make the method wait 3000 ms; after one second you get the error above.
{"action":"configure","config":{"client":{"timeout_ms":1000}}}{"action":"call","method":"ns=2;s=Simulator.Delay","arguments":[{"type":"UInt32","value":3000}]}Simulator.Delay holds the simulator server’s processing thread for that long. New connections aren’t served meanwhile either, so a connect sent right away can also end with Timeout. Reconnect after the delay has passed.
Cancelling requests
Section titled “Cancelling requests”| Method | Effect |
|---|---|
Headless {"action":"cancel"} |
The running action ends with Cancelled. |
| GUI Cancel request | Requests the same cancellation. |
MCP notifications/cancelled |
Interrupts that request and sends no reply. |
Cancelling only stops the simulator client from waiting; it doesn’t undo a request already sent to the server. Responses that arrive later are discarded. client.pending_cancelled in state counts the responses not yet discarded.
Reading error information
Section titled “Reading error information”SDK. Right after a failed function, on the same thread, read the error text with pdcomm_opcua_last_error_copy; C++ pdcomm::opcua::error::what() and .NET OpcUaException.Message hold the same text. Check a response’s service result in service_status and its kind in binary_id from pdcomm_opcua_response_get_info; a binary_id of 397 is a ServiceFault. The SDK library doesn’t write log files.
The simulator’s action record. {"action":"trace"}, or the Trace & Diagnostics tab of the GUI, shows the latest 1000 actions, each with its workspace, action, success, elapsed time in microseconds, target node and error text:
{"action":"call","elapsed_us":210145,"error":"Cancelled","ok":false,"sequence":3,"time_ms":412,"workspace":"read_write_methods"}The server’s audit record. The audit of {"action":"server_status"} keeps the latest 100 secure channel, session and user authentication events of the simulator’s server:
{"action":"user authentication rejected","channel":3,"status":"BadUserAccessDenied (0x801F0000)"}Diagnostic log
Section titled “Diagnostic log”The simulator programs (GUI, headless and MCP) write a diagnostic log as JSON lines. It’s off by default.
Turn it on with an action. Pass the settings to logging_configure. In the GUI, use Diagnostic log (off by default) and Apply logging on the Trace & Diagnostics tab.
{"action":"logging_configure","config":{"enabled":true,"level":"debug","file":"logs/opcua-simulator.jsonl"}}| Field | Default | Description |
|---|---|---|
enabled |
true |
Whether to write the log |
level |
info |
error, warn, info, debug or trace |
file |
None | The log file; without it, the log goes to standard error. The folder must exist. |
max_bytes |
10485760 | The file rotates when it grows past this size. |
files |
3 | Number of files to keep (1 to 16) |
forensics |
false |
Records the process state every second; only with debug or higher. |
Turn it on with environment variables. To log from the moment the program starts, use environment variables:
mkdir -p logsPDCOMM_LOG=debug PDCOMM_LOG_FILE=logs/opcua-simulator.jsonl "$OPCUA_APPS/bin/pdcomm-opcua-headless"The variables are PDCOMM_LOG (the level), PDCOMM_LOG_FILE, PDCOMM_LOG_MAX_BYTES, PDCOMM_LOG_FILES and PDCOMM_LOG_FORENSICS.
One record looks like this; failed actions are logged at the error level:
{"arch":"aarch64","build_id":"4115d51b3c0114ac8ea1edc0786f07c726b87d8a","component":"service","event":"action_completed","fields":{"action":"connect","elapsed_us":5,"error_code":"ServiceError","success":false},"instance_id":"94497-1791998764824784000","level":"error","monotonic_us":197102,"os":"macos","pid":94497,"protocol":"opcua","request_id":7,"schema_version":1,"sdk_version":"0.1.0","sequence":8,"thread":"ThreadId(1)","timestamp_unix_ms":1791998765021}The log records action names, success, an error category (Timeout, Cancelled or ServiceError) and elapsed times. It never contains node values, passwords or private keys. {"action":"logging_status"} shows how many records were written (written) or dropped (dropped) and how many writes failed, and {"action":"logging_flush"} writes the buffer to the file.
| Reply | Cause and fix |
|---|---|
Cannot open logging sink |
The log file’s folder doesn’t exist or isn’t writable; create the folder. |
Invalid logging level |
The level value is wrong. |
Forensics requires debug or trace logging |
Turn on forensics only with the debug or trace level. |
When you report a problem, send the steps to reproduce it, the error text, the action record and the diagnostic log file. The log contains no passwords, but check it for things like file paths before you send it.