Status code · Connection

BadServerTooBusy

BadServer limits

BadServerTooBusy is the server refusing a service call at the application layer because it is at capacity. Unlike BadTcpServerTooBusy, which refuses the transport handshake, this arrives on an established session. Back off with jitter, reduce concurrent work per client, and stop retrying immediately - retries are what keep the server busy.

Defined behaviour: The server is too busy to process the request at this time - the service was refused by admission control rather than attempted and failed. (our description of the condition this code reports)

What you actually see

Requests are refused quickly and cleanly on a connection that is otherwise healthy, in bursts that correlate with plant startup, a server restart or a scheduled bulk read.

Why it happens

  • Connect storm and its retry loopAfter a power event or a server restart every client dials at once. Session establishment is CPU-bound on the RSA handshake and chain validation, so the server queues behind cryptography. A fast deterministic refusal is the correct server behaviour; a client that retries immediately turns it into a positive-feedback loop.
  • Too much concurrent work from too few clientsA collector that fires thousands of reads, a browse of an entire address space, and a subscription rebuild at the same moment can saturate a server on its own. The refusal is admission control protecting the clients that are already being served.
  • The server shares a CPU with something more importantOn a PLC-embedded server the control task has priority. Scan-cycle load, a program download, or a burst of alarm activity leaves nothing for OPC UA. The same happens on virtual machines with noisy neighbours.
  • Subscription load beyond what the hardware supportsThousands of monitored items at short publishing intervals, or many distinct publishing intervals each forcing a separate subscription, keep the server permanently near its ceiling. It then refuses new work rather than degrading everyone.
  • Scanning and asset-discovery trafficVulnerability scanners and inventory tools open, probe and abandon connections in bulk. On a small embedded server this alone consumes the budget that real clients need.

How to fix it

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

  1. Honour the refusalWait and retry with an increasing, randomised delay. Never retry immediately: an immediate retry orphans the previous attempt's server-side state and deepens the queue. Bounded exponential backoff with jitter is the single change that resolves most occurrences.
  2. Stagger startup across the fleetGive each client a randomised startup delay so a plant restart does not become a simultaneous connect. This is the most effective client-side measure against connect storms.
  3. Reduce the work per clientOne session per client per endpoint with several subscriptions inside it. Minimise the number of distinct publishing intervals, since each one forces another subscription. Batch reads into chunks rather than issuing thousands at once.
  4. Look at server diagnostics during the burstBrowse Server_ServerDiagnostics and its SessionsDiagnosticsSummary, and watch host CPU at the same time. A CPU pinned during handshakes points at connect load; a CPU pinned continuously points at subscription load.
  5. Put an aggregation layer in front of a weak serverWhere several consumers need the same data from a controller, have one collector hold the session and republish. Embedded servers cope far better with one well-behaved client than with five casual ones.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UA-.NETStandard (C#)The reference server refuses fast and deterministically under load by design, with limits in the ServerConfiguration. It establishes on the order of a thousand or more concurrent sessions cleanly on a typical multi-core machine; beyond that, connect throughput is bounded by handshake CPU.
Siemens S7-1500OPC UA work competes with the scan cycle on the same controller. Refusals here usually mean the client population or the subscription load is too high for the controller, not that a setting is wrong.
node-opcuaconnectionStrategy with maxDelay and randomisation gives backoff with jitter without extra code. Set maxRetry deliberately rather than leaving an unbounded loop hammering a struggling server.
OPC PublisherStagger endpoint startup instead of declaring hundreds of endpoints that all dial at once, and watch the reconnect metrics after a module restart.
IgnitionSeveral device connections pointed at one small server multiply handshakes and subscriptions. Consolidate to a single connection with multiple tag groups where the data source is the same.

What it looks like in the log

Service call rejected: BadServerTooBusy
Admission control refused CreateSession from urn:collector01:MyCollector; queue depth 38
Retrying in 4200 ms after BadServerTooBusy (attempt 3 of 8)

Confirm the fix

Restart the server with staggered client startup and confirm every client connects on its first or second attempt with server CPU staying below saturation through the burst.

Stop it happening again

Mandate backoff with jitter and randomised startup in client configuration standards, keep one session per client per endpoint, minimise distinct publishing intervals, and alarm on refusal counts before they become an outage.

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