The source code looks like:
I have found that
SecurityTokens have a finite lifetime negotiated with this Service. However, differences between the system clocks on different machines and network latencies mean that valid Messages could arrive after the token has expired. To prevent valid Messages from being discarded, the applications should do the following:
- Clients should request a new SecurityToken after 75 % of its lifetime has elapsed. This should ensure that Clients will receive the new SecurityToken before the old one actually expires.
How can I achieve this? Is this an error when I call the ConnectAsync function? It's taken from ConsoleReferenceClient
For the function connect i use a function similar to this.
/// Creates a session with the UA server
public async Task<bool> ConnectAsync(string ServerUrl)
// Get the endpoint by connecting to server's discovery endpoint.
// Try to find the first endopint without security.
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, ServerUrl, false);
EndpointConfiguration endpointConfiguration = EndpointConfiguration.Create(m_configuration);
ConfiguredEndpoint endpoint = new ConfiguredEndpoint(null, endpointDescription, endpointConfiguration);
// Create the session
Session session = await Session.Create(
30 * 60 * 1000,
// Assign the created session
if (session != null && session.Connected)
m_session = session;
catch (Exception ex)
// Log Error
I have made a client that talk to a server through a dedicated ethernet line connected directly to the server.
After days functioning without any problem, one night it reported some exception while communicating with a server.
It was writing a node value and the error was Opc.Ua.ServiceResultException: BadSecureChannelClosed at Opc.Ua.Bindings.ChannelAsyncOperation`1.End
What can be the cause of this problem? Can it be connected to a mistake at the server side or to a problem at the client?
In case of an error of this type, what is the best way to act in order to retrieve the communication?
I tried to disconnect and reconnect the cable in order to replicate the problem, but I couldn't replicate it.
Time: 03.59.46 --- OPCUA Client 1 Msg = Opc.Ua.ServiceResultException: BadSecureChannelClosed
at Opc.Ua.Bindings.ChannelAsyncOperation`1.End(Int32 timeout, Boolean throwOnError)
at Opc.Ua.Bindings.UaSCUaBinaryClientChannel.EndSendRequest(IAsyncResult result)
at Opc.Ua.Bindings.UaSCUaBinaryTransportChannel.EndSendRequest(IAsyncResult result)
at Opc.Ua.Bindings.UaSCUaBinaryTransportChannel.SendRequest(IServiceRequest request)
at Opc.Ua.SessionClient.Write(RequestHeader requestHeader, WriteValueCollection nodesToWrite, StatusCodeCollection& results, DiagnosticInfoCollection& diagnosticInfos)
at bsOpcUaClientLibrary.UAClient.WriteNodes(DataToExchange Data) in C:\work\OPC_UA_Libraries\OpcUaClient\Rilasciati\v01\DotNet\OpcUaClient\DLL\UAClient.vb:line 221
The exception is repeated many time, it looks as the client try to write the variable in the server again and again
Please make sure you are using the latest version of the UANETStandard codebase.
Potential sources of the error:
1) Network glitch closing the socket (bad cable, h/w, RF interference etc.);
2) Security key re-negotiation glitch or sequence number rollover.
3) Some variation in your program that resulted in a request or response that is too large.
You need to ensure the server log is turned on so you can check for more detailed errors on that side.
1) Hw interference can be a possibility. It should be noted however that the error remains for 3 seconds and during that time the client tried to send 16 times the same writing (the exception was repeated 16 times)
2) when I call CoreClientUtils.SelectEndpoint with the last parameter as false I think the connection is without encription? Am I Right? So It shouldn't be security key renegotiation. What is Sequence number rollover and how can I correct?
EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(m_configuration, ServerUrl, false);
3) I didn't changed my program (the OPCUA client) but the customer have changed the FW of the OPCUA Server the day before. There is a possibility that something is wrong on that side but I must be sure my code is correct.
The day this error has happened, the machine that has the OPCUA Client has been working for about 4 hours and 15 minutes.
The machine with the OPCUA client usually sends 2 commands every 15 seconds and each command is composed by 2 write nodes separated by 100 ms. We have to add that there is a subscription active with a publishing interval of 1000 ms, and a monitor interval time of 300 ms, to monitor the value of 80 nodes in order to automatically report the variation of this nodes (I don’t know how frequently they change).
So each minutes we have:
4*2*2=16 write operations
Since it worked for 4 hours it should have made
4*60*16 = 3840 write node correctly (about 4000)
But the machine with the OPCUA client has never generate this kind of error before (but as I said the server has been modified by my customer).
The server was made by the customer and is implemented in a microprocessor. I don't know if they have the possibility to retrieve the server log (the microprocessor have to drive a motor and likely they don't have implemented an operating system for log file export).
I understand that this make it difficult to understand what happened.
Is it possible that a keep alive is needed? I didn't create one.
I see that looking at QuickstartReferenceClient instead of Console reference client there is a keep alive
I think that the function is to avoid automatic disconnection if there is not communication. Right?
The keep alive is used to recover a connection after an interruption.
It would not cause an interruption.
You have too little data to trigger a sequence number rollover so that is not an issue.
Have you tried wireshark? It has a OPC UA plug in.
It can be used to capture more detailed failure information.
One time I found a bug where a message buffer was getting overridden due to a threading issue. This was found from the wireshark trace where the contents the message before the failure was obviously corrupted.
The problem happened again, this time after 10 minutes of operation. It seems to happens randomly.
I do have wireshark, I didn't know of this plug-in! This plug-in will be very useful! This way I can find easily if the server send the wrong packets or the client misinterpreted them! I found how to activate it. Many thanks.
At the moment the problem is that the customer is abroad, they don't allow us to stop the machine from working, and the connection is a direct connection between a PC (that host the opcua client) and a microprocessor board (that host the opcua server) and it's not connected to internet. We will try to activate wireshark with this option on that machine or at least to have the microprocessor board here to test the communication. The problem however seems to happen after they have updated the FW of the microprocessor that works as opcua server, but I don't know if with this update a previous bug in the opcua client emerge, or if this is a bug in the OPCUA server on the microprocessor.
one question more. I had created my own server on a PC and i'm using it to test the client to see any mistake (I have a lot of report there).
The OPCUA server on my PC uses the socket: 26543
The OPCUA server on the microprocessor of the customer uses the socket 4840
When connecting the client to the server on the microprocessor I need to write only to connect to the IP address: opc.tcp://220.127.116.11
and the connection start without problem
When connecting to the OCPUA server on my PC I need to specify the socket of the Server in the connection opc.tcp://18.104.22.168:26543
I can't change the socket port of the server on my pc by modifying the configuration file to 4840 because while connecting it rises an exception. I can set many other socket but not 4840.
If I modify the configuration file of the client including the socket 26543 as WellKnownDiscoveryUrls (see below)
The client doesn't find the Server on my pc the same unless I set the server socket in the connection url. When it doesn't find it report an exception of BadSecureChannelClosed. Why?
1) To make sure: every well designed OPC UA client should be able to automatically recover from short network interruptions with no loss of data. The logic you need to implement is here: https://reference.opcfoundatio.....Part4/6.7/
IOW, while it is important to find a explanation for the unexpected behaviour it should have zero impact on a production system if you have designed your client correctly. Can you confirm that you have implemented the recovery logic?
2) Windows systems have an LDS running on port 4840. You need to stop this service if you want to use 4840. You can do this from the service control panel.
3) The LDS is used to "discover" servers running on PC but it requires that the Servers register with the LDS. The WellKnownDiscoveryUrls settings you are the location of the LDS on a server if you change. If the Server does not register with the LDS or if the LDS is not running the only way to connect is to enter the exact host/port that the server is using.
I'm trying to implement the monitor of connection.
First of all I tink the first action is to ping the IP address of the server. If it doesn't answer the cable is disconnected and the connection is down. Connecting to the server is impossible.
If the ping works, looking on Forum I found that one way is reading the node "ns=0;i=2267" (for example every 10 seconds). I had to reduced the operation timeout to 3 second.
This way the Session.Read create an exception if the opcua server is down which I use to signal the lack of connection with the server.
The connection doesn't restart by itself even if I turn on the server again, so I need to try to restart the connection.
Now I want to understand what should I do (when the server was down I need to recreate the session I think). Calling Session recreate don't work, so I think I have to close the connection (just in case) and try to restart everything calling Session.Create (if this call don't work the server is still down), if it work i need to Create a new Subscription with monitored Item and so on.
To shorten the connection time, do I need to reduce the Default session timeout in the configuration file?
Below the documentation i found on the forum
You are using different terms than are in the specification.
There is no need to ping.
Simple reading the ServerState is a sufficient watchdog.
If the watchdog fails you close the SecureChannel, create a new one and call ActivateSession.
If that fails, close the Session but do not delete the Subscriptions.
Create a new SecureChannel and Session and attempt to transfer the subscriptions.
If transfer fails re-create your subscriptions.
This is explained in the diagram I linked.