Status code · Subscriptions

BadTooManyOperations

BadBatch limits

BadTooManyOperations means one request carried more operations than the server allows for that service. Servers publish per-service caps such as MaxNodesPerRead, MaxNodesPerWrite, MaxNodesPerBrowse and MaxMonitoredItemsPerCall in ServerCapabilities. Read those values at connect and chunk your batches below them.

Defined behaviour: The request contains more operations in one call than the server permits for that service. (our description of the condition this code reports)

What you actually see

A large Read, Write, Browse or CreateMonitoredItems call is rejected outright with this code as a whole-request error, while the same nodes succeed when sent in smaller batches.

Why it happens

  • Batch larger than the per-service operation limitEach service has its own limit, and they are not the same number. A client that chunks Reads at a thousand nodes but sends Browse in one go will pass the first and fail the second. The limits are per call, so the failure is deterministic and depends only on batch size.
  • Client not reading the advertised limitsThe ServerCapabilities object under the Server object publishes the operation limits the server enforces. A client with a hardcoded chunk size works until it meets a server with a smaller cap, typically an embedded one. Reading the limits at connect and sizing chunks from them removes the class of failure entirely.
  • Generated request from a whole-model traversalCode that browses the address space and then reads every node it found in one call scales with the model. It passes on a small test server and fails on a real plant server with tens of thousands of nodes. The same pattern appears in TranslateBrowsePathsToNodeIds when a path list is built from a whole model.
  • Monitored item creation in one oversized callMaxMonitoredItemsPerCall limits how many items one CreateMonitoredItems request may carry, which is separate from how many items a subscription may hold. A client can be well inside the subscription capacity and still be refused for sending them all at once.
  • Limit of zero meaning no advertised limitA server may publish zero for an operation limit, which conventionally means it does not advertise one rather than that it permits none. A client that treats zero literally will chunk at zero and send nothing; one that treats it as unlimited may then be rejected by an undocumented internal cap.

How to fix it

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

  1. Read the operation limits at connectBrowse to ServerCapabilities under the Server object and read the OperationLimits properties: MaxNodesPerRead, MaxNodesPerWrite, MaxNodesPerBrowse, MaxNodesPerTranslateBrowsePathsToNodeIds, MaxNodesPerMethodCall, MaxNodesPerHistoryReadData, MaxMonitoredItemsPerCall. Cache them per endpoint.
  2. Chunk every batching call against its own limitUse a per-service chunk size, not one global constant. Where a limit is absent or zero, fall back to a conservative default such as a few hundred operations and treat it as a guess rather than as unlimited.
  3. Distinguish the whole-request error from per-item errorsThis code arrives as the service-level result, so there are no per-operation results to inspect. Your error handling must handle the whole-batch failure path, splitting and resending, rather than only walking a results array.
  4. Halve and retry as a safety netWhere a server enforces a cap it did not advertise, a client that halves the batch and retries on this code will converge on a working size without operator intervention. Bound the recursion and log the size that finally worked so it can be configured properly.
  5. Reduce the work rather than the batch where you canFilter Browse by ReferenceTypeId, IncludeSubtypes, NodeClassMask and ResultMask instead of browsing everything, and use TranslateBrowsePathsToNodeIds once at startup rather than repeated traversal. Fewer operations is better than more chunks.
  6. Register nodes you read repeatedlyRegisterNodes gives the server a chance to optimise repeated access to the same nodes and keeps your steady-state Read batches smaller and cheaper. Unregister on shutdown.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UA-.NETStandard (C#)The session exposes the server's OperationLimits after connect and the managed helpers chunk accordingly. Hand-written ReadAsync calls with a large NodeId list bypass that and produce this code.
asyncua (Python)Client.read_values and the bulk write helpers issue one service call for the whole list. Chunk the list yourself using the values read from the server's OperationLimits nodes.
node-opcuasession.read accepts an array that becomes one request. The library exposes the server's operation limits after connect; use them to size the array.
open62541 (C)The read request is built with a fixed array of read value ids, so chunking is entirely the caller's responsibility. Add the chunk loop around your request construction.
UaExpertThe tool chunks its own requests, so if UaExpert can read a node set your client cannot, batch size in your client is the first thing to check.
Siemens S7-1500The integrated server enforces conservative per-call limits compared with PC-based servers. Confirm the current values for your CPU and firmware with the vendor and read the advertised limits at connect rather than assuming.

What it looks like in the log

Read failed: BadTooManyOperations (2500 nodes requested, MaxNodesPerRead 1000)
Browse rejected; splitting 4000 nodes into 4 requests
CreateMonitoredItems: MaxMonitoredItemsPerCall exceeded

Confirm the fix

Confirm the chunked calls all return service-level success with per-operation results, and log the effective chunk size against each endpoint so you can see the client is using the server's advertised limits rather than a default.

Stop it happening again

Make reading OperationLimits part of the connect sequence, drive all batching from those values with a conservative fallback where a limit is absent, and keep a halve-and-retry safety net so an unadvertised cap degrades gracefully.

Verify before you rely on this: Per-service operation limits differ by server product and by firmware on embedded servers; read the advertised values at connect and confirm anything you need to design against with the vendor.

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