Status code · Channels

BadSecureChannelClosed

BadLifecycle

BadSecureChannelClosed means the UASC secure channel carrying your request no longer exists - it was closed by either peer, or the underlying socket dropped. The session may still be valid: open a new secure channel and re-bind or recreate the session, then transfer subscriptions rather than rebuilding everything.

Defined behaviour: The SecureChannel has been closed, so the request cannot be processed on it. (our description of the condition this code reports)

What you actually see

Requests fail as a group the moment the channel goes, typically with outstanding Publish requests completing first, and the client's connection state flips to reconnecting.

Why it happens

  • The TCP connection droppedA network blip, a switch failover, a VPN renegotiation or a firewall idle timer tears down the socket, and the channel dies with it. This is the most frequent cause, and it is why secure channel and session are separate concepts: the session can survive and be re-bound to a fresh channel.
  • Channel token renewal failedChannels have renewable security tokens with a limited lifetime. If a RenewSecureChannel does not complete in time - commonly because the client was blocked or the link was congested - the server closes the channel. You may see BadSecureChannelTokenUnknown just before this.
  • The client or server closed it deliberatelyCloseSecureChannel on client shutdown, a server going into shutdown, or a reverse-connect client fetching endpoints all close channels. In the reverse-connect case this is expected behaviour, not a fault.
  • Server-side error handling closed the channelA decoding error, an oversized message, or a security check failure is often handled by aborting the channel rather than returning a per-request fault. The visible code is then BadSecureChannelClosed and the actual reason only appears in the server log.
  • A stateful middlebox interferedNAT gateways, load balancers and TLS-terminating proxies in front of opc.tcp on 4840 do not understand UASC framing. Session-based load balancing across two server instances in particular closes channels unpredictably.

How to fix it

In diagnostic order: work down, do not skip ahead.

  1. Confirm whether the socket or the channel went firstCorrelate the client fault with the TCP state. A capture on port 4840, or ss output on the client, tells you whether you saw a RST or FIN before the fault or whether the channel was closed at the protocol level with the socket intact.
  2. Check for token renewal problemsLook in the client log for RenewSecureChannel activity and its timing relative to the failure. Renewals that consistently land close to token expiry mean the client is starved or the round-trip time is too long for the configured lifetime.
  3. Read the server log for the real reasonWhere the server aborted the channel on purpose, the cause is only in its own log - decoding error, message size limit, security check failure. Do not diagnose from the client side alone.
  4. Reconnect through the channel, not the applicationOpen a new secure channel and re-bind or recreate the session, then call TransferSubscriptions and handle GoodSubscriptionTransferred. Rebuilding every monitored item on each blip is what turns a two-second outage into a two-minute data gap.
  5. Remove or fix middleboxes in the pathVerify you are talking to one server instance and not a load-balanced pair. Where NAT is unavoidable, use reverse connect so the server dials out on opc.tcp and only outbound flows are needed.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UA-.NETStandard (C#)SessionReconnectHandler re-establishes the channel and re-binds the session; the decoupling of channel and session is what makes this possible. Watch for repeated reconnects, which indicate an unstable path rather than a code problem.
node-opcuaThe client emits connection_lost and start_reconnection, then attempts subscription re-establishment. Tune connectionStrategy rather than writing your own retry loop.
open62541 (C)The client state callback reports the channel state separately from the session state, which makes it easy to log which layer failed. Keep calling UA_Client_run_iterate during reconnect.
OPC PublisherReconnects and re-subscribes automatically, but repeated channel loss shows up as gaps in published telemetry rather than as an obvious error. Watch the diagnostic output for reconnect counts.
Wireshark OPC UA dissectorDistinguishes CLO, ERR and MSG frames, so you can see whether the channel was closed politely, aborted with an error, or simply lost with the TCP connection.

What it looks like in the log

Publish completed with BadSecureChannelClosed; channel 12 is gone
Channel closed by peer (CLO) - reconnecting secure channel to opc.tcp://plc01:4840
SecureChannel 12 aborted: decoding error while processing request

Confirm the fix

After the fix, run the client for a shift and count channel reconnects. Zero or a handful correlated with known network events is healthy; a regular cadence points at token lifetime or an idle timer.

Stop it happening again

Keep OPC UA traffic on a path with no session-affinity load balancers, use reverse connect across network layers, and standardise on a reconnect helper that transfers subscriptions instead of recreating them.

Stuck on more than one of these? The troubleshooting clinic works through broken configurations end to end, on camera.

Troubleshooting clinic →

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Status Code Diagnostic Tree
A 15-page diagnostic reference grouping every normative status code by what actually went wrong: with the first action for each, and the four questions that resolve most faults before you read a single code.
Get the free diagnostic tree →
Free, no course, no login