Status code · Subscriptions

BadSubscriptionIdInvalid

BadLifecycle

BadSubscriptionIdInvalid means the server has no subscription with that id on this session. It is almost always a subscription the server already deleted - lifetime expiry, session loss, or a reconnect that did not transfer it. Recreate the subscription and its monitored items rather than retrying Publish.

Defined behaviour: The subscription identifier in the request does not refer to a subscription that exists on this session. (our description of the condition this code reports)

What you actually see

Publish calls that were working start returning this code on every attempt, and no further data change notifications arrive, while a plain Read on the same session still succeeds.

Why it happens

  • Subscription lifetime expired because the client stopped publishingA subscription is kept alive by outstanding Publish requests. LifetimeCount is expressed in publishing intervals, and when that many intervals pass with no Publish to send notifications on, the server deletes the subscription and tells you so the next time you reference it. A client blocked on a slow downstream sink is the usual reason it stopped publishing.
  • Reconnect created a new session without transferring subscriptionsSubscriptions belong to a session. If your reconnect logic creates a fresh session instead of re-activating the old one, or calls TransferSubscriptions and ignores a failure, the old subscription ids are meaningless on the new session. The client keeps using the cached ids and gets this code for each of them.
  • Client cached the id across a server restartSubscription ids are assigned by the server and are not stable across restarts. A collector that persists ids to disk, or a long-lived process that never invalidates its cache, will use a stale id after the server bounces.
  • DeleteSubscriptions already succeededA second delete, or a delete racing with an in-flight Publish, returns this code. It is benign but it fills logs. Shutdown code that deletes subscriptions and then waits for the last Publish responses will see it every time.
  • Server-side resource reclaimUnder pressure some servers reclaim subscriptions, especially ones with no outstanding Publish or a very long publishing interval. There is no notification when this happens - the only signal is this code on the next reference to the id.

How to fix it

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

  1. Treat the code as a rebuild trigger, not a retry conditionRetrying Publish with the same id will never succeed. On this code, drop the local subscription object, call CreateSubscription and CreateMonitoredItems again, and re-apply your monitoring modes and filters. Every mature client SDK has a hook for this; use it rather than writing your own retry loop.
  2. Log the revised publishing interval and lifetime you actually gotCreateSubscription returns revised values that can differ substantially from what you asked for. Compute your keep-alive expectation from the revised publishing interval multiplied by the revised LifetimeCount, not from your requested numbers, or your watchdog will be tuned to the wrong deadline.
  3. Keep at least one Publish outstanding at all timesPublish is a long poll. If your code processes a notification synchronously before issuing the next Publish, a slow handler stalls the pipeline and eventually burns through the lifetime. Queue notifications to a worker and reissue Publish immediately.
  4. Fix reconnect to re-activate the session or transfer explicitlyRe-activate the existing session on a new secure channel where the stack supports it, which preserves subscriptions. Where you must create a new session, call TransferSubscriptions and check every per-item result - a partial success means some subscriptions moved and others must be rebuilt.
  5. Add a subscription watchdogFire an alarm when no notification and no keep-alive has arrived for a multiple of the publishing interval, and have the watchdog rebuild rather than just log. This catches the case where the server silently deleted the subscription and your Publish loop has already given up.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UA-.NETStandard (C#)The Session raises PublishError and the SessionReconnectHandler normally recovers by re-activating and transferring. If you build subscriptions manually, subscribe to Subscription.PublishStatusChanged and rebuild there; do not swallow the transfer result.
node-opcuaClientSubscription emits an error carrying this code once the server has dropped it. Use the managed client's automatic re-creation of subscriptions on reconnect instead of caching subscriptionId yourself.
asyncua (Python)The client's subscription object holds subscription_id. After a reconnect check whether your code re-created subscriptions or reused ids; a Publish worker that logs and continues will loop on this code forever.
open62541 (C)The client sets a subscription inactivity callback for exactly this case. Implement it and rebuild the subscription there; the default is to do nothing, which looks like a silent data stop.
UaExpertThe Data Access View stops updating and the log shows repeated publish failures. Removing and re-adding the view, or reconnecting the session, rebuilds the subscription and confirms the server side is healthy.
OPC PublisherConfiguration changes and endpoint reconnects rebuild subscriptions, and this code appears in the logs during the transition. Persistent occurrences point at lifetime expiry from stalled publishing rather than at configuration.

What it looks like in the log

Publish failed for subscription 4: BadSubscriptionIdInvalid
Subscription 4 no longer exists on the server; recreating with 128 monitored items
TransferSubscriptions returned BadSubscriptionIdInvalid for 2 of 3 subscriptions

Confirm the fix

After rebuilding, confirm the new subscription id appears in your logs alongside the revised publishing interval, and that keep-alive messages arrive on schedule with no further occurrences of the code over several lifetime periods.

Stop it happening again

Never persist or hardcode subscription ids, keep one or more Publish requests outstanding continuously, derive watchdog timeouts from the revised publishing interval and LifetimeCount, and make reconnect either re-activate the session or check every TransferSubscriptions result.

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