# Description Findings of a full CTT run (23 parts, 3,752 test cases, CTT 1.05.06 / scripts 1.05.513) against the merge of #4477, #4482, #4485 and #4486, which are all on master now, plus the CTT defects filed in Mantis. No server code changes: the PR changes only the CTT configuration of the reference server sample and the `plans/` documentation. ## CTT configuration: raise `ChannelLifetime` to 120 s CTT Security None `007.js` and Security Basic256Sha256 `005.js` failed (also on master): they keep SecureChannels without a Session idle for about 51 s (60 s token, stretched by the CTT's CloseSession delay, C50) and expect the newest one to close with Good. `TcpTransportListener.DetectInactiveChannels` had already closed it after `ChannelLifetime` (30 s) without traffic (`CloseSecureChannel().Result received BadInvalidState`). `samples/Reference/ConsoleReferenceServer/Ctt.ReferenceServer.Config.xml` now sets `ChannelLifetime` to 120000. The default of 30000 and the server's inactivity cleanup are unchanged. An earlier revision of this PR changed the inactivity cleanup instead, keeping idle Session-less channels open until their token expired (Part 4 §5.6.2.1). That change was withdrawn because it lets an unauthenticated client hold a channel for up to the `SecurityTokenLifetime` (one hour by default) instead of 30 s. The difference to Part 4 §5.6.2.1 is recorded as an open server finding in `plans/ctt-issues.md`. Validated on 2026-09-24 with the reverted code and the new configuration (full run, compared with the run of 2026-09-22 at test-case level): - Security None `007.js` passes and Security Basic256Sha256 `005.js` has only the C50 CloseSession delay warnings (both failed with 30 s). - All other parts have the same error signatures as before; the remaining differences are *"Response Timestamp shows a delay"* warnings from a loaded machine (a back-to-back Session Services run with 30 s and 120 s on an idle machine is identical). - A & C Refresh2 `Err_003.js`/`Err_004.js` and Shelving `initialize.js` report `BadSubscriptionIdInvalid` in today's runs with both 30 s and 120 s on the same build, so they are unrelated to the configuration (both passed again in a run on the idle machine with 120 s). ## Mantis 32 CTT defects filed on 2026-09-24 (11420–11454, script issues in *CTT UA Scripts*, native aggregate oracle issues in *CTT UA Binary*); 12 drafts were already covered by existing reports (including GDS issues 11406–11413 by node-opcua and 11102 for the `opc.https`/`opc.wss` endpoint selection); 5 are held back for further investigation. `plans/ctt-issues.md` links every entry. ## CTT documentation (`plans/ctt-issues.md`, `plans/ctt-testing.md`) - `ctt-issues.md` lists every failing CTT test case with a short abstract and its Mantis issue; the details live in Mantis. It keeps the defects not filed yet, the open questions (U1–U4), the open server findings and the CTT project configuration notes, and no longer lists findings the server has fixed. - Notable CTT findings of this run: the aggregate oracle lacks the Part 13 Uncertain status and Calculated bit rules that #4477 implements (C48/C49, 24 test cases); the CloseSession "delay in excess of 600ms" warnings are a CTT client artifact (C50: the server answers in 2–5 ms, the CTT stops the Session's SessionThread between stamping and sending); the CTT's `FindTokenType` rewrites its cached endpoints, so Security User Name Password 2 `015.js` reports duplicate PolicyIds (C36); A & C Comment passes or skips depending on the date (C39). - Open server finding: AddNodes after a child rename returns `BadNodeIdExists` (#4477 × #4486 interaction, not covered by the CTT). - `ctt-testing.md` is a runbook for agents: setup, headless runs, selection generation, reading and comparing results, triage, recipes per conformance group (A & C, Session/Subscription, Monitored Items, security groups with an isolated PKI) and a full partitioned run of every group (about 80 minutes). It points to `ctt-issues.md` for the failures to expect. ## Related Issues - Follow-up to #4477, #4482, #4485, #4486 ## Checklist - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [ ] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [ ] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received. Validated locally with a full partitioned CTT run of the Release net10.0 reference server (reverted code, `ChannelLifetime` 120000). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
OPC Foundation UA .NET Standard Reference Server
Introduction
The console reference server can be configured using several console parameters. Some of these parameters are explained in more detail below.
To see all available parameters call console reference server with the parameter -h.
Historical Access
The reference server starts with an in-memory Part 11 historian. Its historized
scalar nodes expose raw, modified, at-time, aggregate, annotation, and update
operations together with populated HistoricalDataConfigurationType
companions. CTT/Historical_KeyValuePairs demonstrates generic
StructuredHistoryData with two KeyValuePair entries at one timestamp. The
CTT notifier exposes historical event read/write bits, a
HistoricalEventConfigurationType companion, and seeded event history.
Writes to the two event-trigger variables report events; live forwarding
completes before the historian snapshots them into its bounded asynchronous
capture queue.
Run the matching client workflow with:
dotnet ConsoleReferenceClient.dll --historian --autoaccept --nosecurity \
opc.tcp://localhost:62541/Quickstarts/ReferenceServer
See docs/HistoricalAccess.md for the
provider contracts, status semantics, and custom storage examples.
Reverse Connect
The OPC UA reverse connect feature allows an OPC UA server to initiate the connection to a client, rather than the traditional model where clients connect to servers. This is particularly useful in scenarios where the server is behind a firewall or NAT, making it difficult for clients to directly connect to it.
How to use Reverse Connect
To enable reverse connect mode, specify the client endpoint URL using the --rc or --reverseconnect parameter:
dotnet ConsoleReferenceServer.dll --rc=opc.tcp://localhost:65300
or
dotnet ConsoleReferenceServer.dll --reverseconnect=opc.tcp://localhost:65300
Example: Server and Client with Reverse Connect
-
Start the client with reverse connect listener on port 65300:
dotnet ConsoleReferenceClient.dll --rc=opc.tcp://localhost:65300 opc.tcp://localhost:62541/Quickstarts/ReferenceServer -
In a separate terminal, start the server with reverse connect to the client:
dotnet ConsoleReferenceServer.dll --rc=opc.tcp://localhost:65300 -a
The server will establish a reverse connection to the client endpoint, and the client will use this connection to communicate with the server.
Additional Options
-aor--autoaccept: Auto accept untrusted certificates (for testing only)-cor--console: Log to console-lor--log: Log app output-tor--timeout: Timeout in seconds to exit application
For the complete list of options, use --help.
X509 user identity certificates
The reference server validates X509 user identity tokens against its trusted-user certificate
store (TrustedUserCertificates, by default %LocalApplicationData%/OPC Foundation/pki/trustedUser).
An untrusted user certificate is rejected with BadIdentityTokenRejected — the --autoaccept option
only auto-accepts the application/channel certificate, never user identity certificates.
To let a trusted client (for example the OPC Foundation Compliance Test Tool) authenticate with an
X509 user token, its user certificate must be present in that store. To make provisioning easy, the
server writes every rejected X509 user certificate to a dedicated review store,
pki/rejectedUser (a sibling of pki/trustedUser). After one failing activation you can move the
legitimate user certificate from pki/rejectedUser/certs into pki/trustedUser/certs (and any
issuing CA into pki/issuerUser/certs) and reconnect. Deliberately-untrusted certificates simply stay
out of the trusted store and continue to be rejected.