BadNothingToDo
BadEmpty request
BadNothingToDo means you sent a service request with an empty operation array: a Read with no nodes, a Write with no values, a CreateMonitoredItems with no items. The server refuses rather than returning an empty success, so fix the code that built the empty list.
What you actually see
A service call fails instantly with no per-operation results at all, usually right after a configuration load or a filtering step in the client.
Why it happens
- A filter removed every itemClient code that filters a tag list by device, area or enable flag can legitimately produce an empty list, then send the request anyway. This shows up the first time a machine is disabled or a filter is tightened.
- Configuration loaded from an empty or missing fileA tag configuration that failed to parse, or a path that resolved to an empty file, leaves the collector with nothing to subscribe to. The empty request is the first visible symptom of a configuration problem upstream.
- A batching loop that emits a final empty chunkSplitting a list into batches with a size that divides evenly often produces one trailing empty batch. Every batch succeeds except the last one, which makes it look intermittent in the logs.
- All operations already deduplicated awayDeduplication against an existing subscription can remove every candidate, leaving nothing new to create. The correct behaviour is to skip the call, not to send an empty one.
- An optional request field left unsetBuilding a request object without populating its operation array at all, for example forgetting to assign nodesToRead, sends a structurally valid request with nothing in it.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Guard every service call on a non-empty listCheck the length of the operation array immediately before sending, and skip the call when it is zero. This is a one-line fix and it eliminates the code entirely.
- Log why the list was emptyWhen you skip the call, log the reason: no tags matched, configuration file empty, everything deduplicated. An empty list is often the real bug, and silently skipping hides it.
- Validate configuration at load timeFail loudly at startup if the tag configuration parsed to zero entries. A collector that starts cleanly and collects nothing is much harder to notice than one that refuses to start.
- Fix the batching boundaryUse a chunking helper that never emits an empty final chunk, and assert the invariant in a unit test with list lengths that are exact multiples of the batch size.
- Check operation limits while you are thereThe same code path that can send zero operations can also send too many. Read Server/ServerCapabilities/OperationLimits and clamp batch sizes to the advertised maximum per service.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| asyncua (Python) | client.read_values([]) or a batch write with an empty list produces this. Guard the call site rather than catching the exception. |
| node-opcua | session.read([]) and createMonitoredItems with an empty item array both send an empty request. Filter first, then decide whether to call at all. |
| UA-.NETStandard (C#) | Passing an empty collection to Session.Read or Session.Write reaches the wire. Since the response has no per-operation results, the failure is easy to misread as a connection problem. |
| OPC Publisher | A published-nodes configuration that resolves to zero nodes for an endpoint produces empty requests against that endpoint. Validate the configuration file rather than debugging the server. |
| Ignition | A scripted read or write built from a dynamic tag list can pass an empty array through on the first execution. Guard the call so the OPC UA request is only issued when the list has entries. |
What it looks like in the log
Read request rejected: BadNothingToDo (nodesToRead is empty)
CreateMonitoredItems called with 0 items for subscription 3
Tag configuration loaded: 0 entries matched filter for endpoint opc.tcp://plc01:4840
Confirm the fix
Reload the configuration, confirm the client logs a non-zero operation count for each service call, and check the server returns per-operation results for every request it receives.
Stop it happening again
Assert non-empty operation arrays at the client boundary, fail configuration loading loudly when it yields nothing, and clamp batch sizes to the advertised operation limits at the same guard.
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.