BadNoSubscription
BadLifecycle
BadNoSubscription means you called Publish on a session that has no subscriptions at all. It is the normal response to a Publish issued before CreateSubscription, after the last subscription was deleted, or on a fresh session after a reconnect that lost them. Create a subscription before starting the Publish loop.
What you actually see
The Publish loop returns this code immediately and repeatedly on a session that connects cleanly and can read and browse normally.
Why it happens
- Publish loop started before the first subscription existsHand-written clients often start a background Publish worker at session activation. If CreateSubscription has not completed yet, every Publish in that window returns this code. It is harmless if you handle it, but a worker that treats it as fatal will exit before the subscription is ever created.
- All subscriptions deleted but the loop still runningOn shutdown or reconfiguration the client deletes its subscriptions and the Publish worker keeps going. The code then repeats at whatever rate your loop runs, which can be very fast because Publish returns immediately instead of long-polling.
- Reconnect produced a new session with no subscriptionsSubscriptions live on the session. A reconnect that creates a fresh session, or a TransferSubscriptions that failed entirely, leaves you with a working session and nothing to publish. This is the variant that looks like a silent data stop in production.
- Server deleted the last subscription on lifetime expiryIf the client stalled long enough for LifetimeCount publishing intervals to pass without a Publish, the server deletes the subscription. The next reference to the id gives BadSubscriptionIdInvalid; once nothing is left, further Publish calls give this code instead.
- Subscription creation failed and was not noticedCreateSubscription can fail with a resource or limit error. Code that ignores the response and proceeds straight to publishing will see this code rather than the real reason, which hides a server limit problem behind a symptom.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Order the calls correctlyActivate the session, call CreateSubscription, check its status, call CreateMonitoredItems, then start publishing. Do not run the Publish worker as an independent task that races with setup.
- Back off instead of spinningBecause Publish returns immediately with this code rather than blocking, a tight loop can generate thousands of requests per second and look like a client-side denial of service. Add a bounded delay on this specific code and stop the loop entirely when you have no subscriptions.
- Log the CreateSubscription result including revised valuesCapture the returned subscription id, revised publishing interval, revised LifetimeCount and revised MaxKeepAliveCount. If creation failed, the real error is there and is far more informative than the Publish response.
- Make the Publish worker a dependant of the subscription setStart and stop publishing based on whether any subscription exists. Where the SDK manages this for you, use its managed session or subscription abstraction rather than driving Publish yourself.
- Fix reconnect so subscriptions come backPrefer re-activating the existing session so subscriptions survive. Where a new session is unavoidable, call TransferSubscriptions and rebuild anything it did not move, then confirm the item count matches what you configured.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| UA-.NETStandard (C#) | The Session publishes only while subscriptions exist, so seeing this code usually means custom publish handling. Check that Session.Subscriptions is non-empty after reconnect and that AddSubscription plus Create actually completed. |
| asyncua (Python) | The internal publish task is tied to the client's subscription list. Custom code that calls the raw publish service after delete_subscriptions will produce this; let the library own the loop. |
| node-opcua | The session publish engine stops when the last ClientSubscription terminates. A raw session.publish call outside that lifecycle returns this code. |
| open62541 (C) | UA_Client_run_iterate drives publishing; with no subscription registered there is nothing to publish. Register the subscription before entering the iterate loop. |
| Eclipse Milo (Java) | The subscription manager owns the publish pipeline. If you see this code, verify that the subscription was created on the session that is publishing rather than on a previous one. |
| OPC Publisher | During a configuration reload subscriptions are torn down and rebuilt, so brief occurrences at that moment are expected. Persistent occurrences mean the new subscriptions are not being created, which is a configuration or limits problem. |
What it looks like in the log
Publish returned BadNoSubscription; no subscriptions on session
CreateSubscription failed, continuing to publish loop
Publish loop suspended: subscription count 0
Confirm the fix
Confirm a subscription id is logged from a successful CreateSubscription, then confirm the Publish loop transitions to long-polling with keep-alive messages arriving at the expected multiple of the publishing interval.
Stop it happening again
Tie the Publish loop's lifetime to the existence of subscriptions, always check the CreateSubscription result before publishing, and add a startup assertion that the configured monitored item count matches the count the server confirmed.
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.