Skip to main content

Closing the last gap in OPC UA reconnection

· 6 min read
Etienne Rossignon
Maintainer of NodeOPCUA and @opcua/for-node-red

I wear two hats. I'm the author of node-opcua, the OPC UA stack that powers a large part of the JavaScript OPC UA world, and I'm the author of OPCUA For Node-RED, which is built on top of it. Today I want to talk about a gap I could only really see by wearing both hats at once — and the feature we built to close it.

First, credit where it's due: the OPC UA standard

Before I talk about what we added, I want to be clear about what was already right — and that credit belongs, first of all, to the OPC UA specification itself.

Reconnection in OPC UA is not an afterthought; it is designed into the standard with real care. The spec separates the secure channel, the session and the subscription lifecycles so that they can survive independently, and it gives a client precise, interoperable tools to recover after a disruption — most notably the TransferSubscriptions service (to move live subscriptions and their monitored items onto a fresh session) and Republish (to recover notifications that were in flight). So real kudos to the OPC Foundation and the people who wrote that specification — they thought hard about the messy reality of industrial networks, and it shows.

And yes — node-opcua implements this faithfully and well. When a server reboots or a link blinks, the client transparently re-establishes the secure channel, re-activates the session, transfers the subscriptions and re-creates the monitored items. From your flow's point of view, the connection heals itself and values resume. That part is a given, and it has worked well for years.

…except for one subtle gap

Here is the case that kept nagging me.

When the connection is re-established, the client re-creates each monitored item against the freshly restarted server. That is exactly the right thing to do — if the variables are all there at that moment.

But real servers don't come back all at once. A PLC, a gateway, a line controller — they reboot in stages. The OPC UA endpoint is often listening again well before the address space is fully populated. So when the client reconnects, a chunk of your variables simply aren't there yet. They'll appear a few seconds later, when the device finishes warming up.

At that instant, re-creating those particular monitored items fails with BadNodeIdUnknown, and — correctly, per the spec — they are not retried. The session is restored, the subscription is healthy, the reconnection "succeeded"… and yet a subset of your tags has silently stopped updating — even after the variables reappear seconds later.

That's the insidious part. Nothing looks broken. The connection is green. But your dashboard quietly froze on a handful of tags, and the only cure is a redeploy. This isn't a flaw in the standard or in node-opcua: at the protocol level, monitoring a node that doesn't exist is an error. What was missing was a higher layer that understands intent over time — "I want this tag, and I'm willing to wait for it."

The feature — available today in OPCUA For Node-RED

That layer is exactly what we built, and the first place you can use it is OPCUA For Node-RED. The Monitor node now runs a sophisticated self-healing mechanism on top of the standard reconnection. It:

  • after every reconnection, re-validates your entire monitored set and notices which variables came back missing;
  • keeps a patient, batched retry running for exactly those stragglers — and re-monitors each one the instant it appears, without ever disturbing the tags that are already streaming;
  • treats a not-yet-present variable as pending, never as a dead end — so the same mechanism also covers tags that aren't there at the very first deploy;
  • and, if you want it, re-emits the last value of every tag as BadServerNotConnected the moment the link drops, so downstream logic knows the data is stale instead of trusting a frozen value.

You declare what you want to monitor — single nodes, arrays, or whole structures of NodeIds and browse-paths — and the node makes reality converge to that intent, and keeps it there, across reboots and outages, with no redeploy. As far as I know, this is unique to OPCUA For Node-RED, and I'm genuinely proud of it.

A story in numbers

Here's the scenario I use to prove it — and it's a real automated test that ships with the project.

A server plans 2000 counter variables but defines only 100 at boot. The node is asked to monitor all 2000:

MomentValidBadMissing (pending)
Start (only 100 exist)10001900
Variables appear gradually…500 → 1000 → 15000falling
All present200000
Connection lost020000
Reconnected — server still re-initializing10001900
Repaired again200000

Look at the second-to-last row: the standard reconnection brings back the 100 variables that exist, but 1900 are still warming up. That is precisely the gap. Our layer keeps working and climbs all the way back to 2000 — on its own, no redeploy.

And available to our professional customers, too

We didn't keep this trapped inside the node. The repair engine is a self-contained SmartSubscription that lives in one of our optimized OPC UA client libraries — the same building blocks we use everywhere.

So if you're a Sterfive customer on a professional licence, this advanced smart-monitoring capability is available to you as well: you can embed exactly the same self-healing behavior directly into your own applications and integrations, not just in Node-RED. If that's something you'd benefit from, talk to us — we'd be glad to help you put it to work.

Try it — then pull the cable

Update to the latest OPCUA For Node-RED, point a Monitor node at a structure of tags (throw in a few that don't exist yet), and watch it bring everything online. Then restart your server — better yet, a slow one that boots in stages — and watch it heal back to full health without you lifting a finger.

That last part is the whole point. The messy servers, the staged reboots, the tags that show up late — those are the ones I built this for.

— Etienne