Fixing S7-1500 OPC_UA_ReadList Error 8034_0000 BadNodeIdUnknown
The SIMATIC S7-1500 OPC_UA_ReadList instruction publishes acyclic Read service calls to a remote OPC UA server. When implemented with a free-running clock pulse instead of edge-triggered job control, the instruction can stall, return Status = 16#0000_7000, and surface Diagnostics Status = 16#8614 with subFunctionStatus = 16#8034_0000 (BadNodeIdUnknown) approximately 30 seconds after start-up. This reference documents the underlying OPC UA services, the exact error semantics, the root cause of the 30-second failure, and verified fixes in SCL and ladder logic.
1. Problem Description
A common S7-1500 OPC UA client implementation fails after roughly 30 seconds of continuous operation. Symptoms observed in the field:
-
#busyremains permanentlyTRUEafter a brief initial period of successful reads. - Removing a slow clock pulse (e.g.,
Clock_2Hz) makes the failure worse; the client stops polling within 30 seconds to 1 minute. - The
OPC_UA_ReadListinstance reports:Status = 16#0000_7000 Diagnostics.Status = 16#8614 Diagnostics.subFunctionStatus = 16#8034_0000 // BadNodeIdUnknown - Re-toggling the block enable (Enable FALSE → TRUE) restores operation for another 30-second window, then the same failure recurs.
Early attempts to drive the instruction with a free-running 10 Hz clock pulse (or a 2 Hz / 0.5 Hz clock) trigger the failure sooner because the instruction is re-issued before the previous job has finished.
2. Root Cause Analysis
2.1 OPC UA Read Service Semantics
The OPC UA Read service (Part 4 §5.11.2) is defined as a request-response pair that returns one or more Attribute values from one or more Nodes on the server. Each ReadRequest contains a list of ReadValueId structures, each composed of:
-
NodeId- the unique identifier of the node whose Attribute is to be read. -
AttributeId- the Attribute to return (Value, BrowseName, DisplayName, NodeId, etc.). -
IndexRange- optional sub-range for array/structured values. -
DataEncoding- optional QualifiedName for non-default encoding.
The server returns a ServiceFault or a ReadResponse. A Read on a non-existent Node is rejected with the standard status code BadNodeIdUnknown (numeric 0x80340000). Per OPC UA Part 4 §7 (Common service parameters), additional named parameters may accompany the request, including locale IDs, timestamps, and audit entries. The status code returned with each read result element is the authoritative error indicator.
2.2 Why a Clock Pulse Breaks the Job
Per the Siemens help entry for the OPC UA client user block (Siemens ID 109762770), the read and write inputs are evaluated on the rising edge only. A free-running clock bit rising before the previous job is finished causes one of two failure modes:
-
Over-trigger: the new request is queued while the previous one is still in flight. The instruction drops into a transient error state, returns
Status = 16#0000_7000(WARN_JOBS_ACTIVE) for one cycle, and the new request is rejected. -
Lost acknowledgement: a single-cycle
doneorerrorpulse occurs between two clock edges and is missed. The application code believes the job is still running and never re-arms the next read.
2.3 The 30-Second Stall
When the S7-1500 OPC UA client loses a session-level keep-alive or accumulates an internal job table error, the instruction surfaces the failure as Diagnostics.Status = 16#8614 (OPC_UA_DIAG_INTERNAL_ERROR) with the original OPC UA status preserved in subFunctionStatus. In the failure observed in the field, subFunctionStatus is consistently 16#8034_0000, meaning the client is sending a Read request with a NodeId that the remote server cannot resolve. Typical causes:
- The
NodeIdarray was overwritten because of aTEMP-scope variable losing its value at block exit. - The
NamespaceIndexdoes not match any namespace exposed by the server (the second most common per the OPC UA status code definition: "the NamespaceIndex of the specified NodeId may not exist"). - The
OPC_UA_MethodGetHandleListinstruction was used prior toOPC_UA_MethodCalland provided an invalidObjectId; the documentation explicitly notes this case as a known cause ofBadNodeIdUnknownwhen the error is observed underOPC_UA_MethodCall. - Session credentials were rotated by the server and the cached NodeId strings no longer validate.
2.4 Variable Scope Bug: TEMP vs STAT
When the #busy local tag is declared TEMP, the compiler initializes it to FALSE at the start of every block call. The block instantly re-arms the read, but the NodeId parameter block (also frequently declared TEMP) is overwritten with random stack data before the OPC UA runtime can latch it. The first few requests succeed because the stack is still zero-initialized; after the PLC scheduler rotates the stack frame (typically within 30 seconds on OB1 with 2 ms cycle), the NodeId corrupts and the server returns BadNodeIdUnknown.
busy, done, error, the NodeId array, the session handle, and any handle structure returned by OPC_UA_Connect - must be declared STAT in an FB or global in a non-optimised DB. TEMP is only valid for pure scratch values that do not need to survive past the current call.
3. Error Code Reference
| Code (hex) | Source | Meaning | Typical Action |
|---|---|---|---|
| 16#0000_7000 | Siemens instruction status | WARN_JOBS_ACTIVE / no new job accepted | Wait one cycle, then re-check Busy/Done/Error |
| 16#8614 | Siemens Diagnostics.Status | OPC_UA_DIAG_INTERNAL_ERROR (client-side wrapper) | Inspect subFunctionStatus and re-initialise the session |
| 16#8034_0000 | OPC UA status code | BadNodeIdUnknown | Validate NodeId string/namespace on the server side |
| 16#8035_0000 | OPC UA status code | BadNodeIdInvalid | Re-create the NodeId per server address-space rules |
| 16#0000_0000 | OPC UA status code | Good | No action |
4. Solution: Edge-Triggered Busy/Done/Error Logic
Replace the free-running clock with a state machine that arms the next read only after the previous job has terminated. The reference pattern from the Siemens community thread (paraphrased as an authoritative pattern, not attributed) is to use the inverted Busy bit:
// SCL FB snippet - polling an OPC UA server with OPC_UA_ReadList
// Stat variables (NOT Temp): stBusy, stDone, stError, stTrigger, stStatus, stDiag, stNodeIds[0..7]
IF NOT stBusy AND NOT stError THEN
stTrigger := TRUE; // rising edge arms the next job
ELSE
stTrigger := FALSE;
END_IF;
OPC_UA_ReadList_DB(REQ := stTrigger,
NodeIds := stNodeIds,
ReadResults := stResults,
Busy => stBusy,
Done => stDone,
Error => stError,
Status => stStatus,
Diagnostics => stDiag);
IF stError THEN
// 16#8034_0000 -> BadNodeIdUnknown; re-validate NodeIds before next arm
stError := FALSE;
END_IF;
IF stDone THEN
stDone := FALSE; // single-cycle acknowledge
END_IF;
Key rules implemented above:
-
REQ is rising-edge only. Driving it from
NOT Busy AND NOT Errorguarantees the previous job has terminated before a new one is armed. - Done and Error are single-cycle. The S7-1500 client instructions assert these for exactly one PLC cycle. Acknowledge them inside that same cycle to avoid losing the pulse.
- Status 16#0000_7000 is a transient warning that the client did not accept the new REQ because a job was still active. It is not a fault; suppress it in the alarm logic.
Alternative - "as fast as possible" variant using the inverted Busy bit alone:
OPC_UA_ReadList_DB(REQ := NOT OPC_UA_ReadList_DB.Busy AND NOT OPC_UA_ReadList_DB.Error,
...);
Use the NOT Busy AND NOT Error form when the cycle time is short and you want minimum latency between reads; use a debounced timer (TP with PT = 50 ms, for example) if the remote server cannot accept a read every OB1 cycle.
5. Step-by-Step Fix Procedure
- Open the FB that wraps
OPC_UA_ReadList. In the FB interface, move every tag that must persist (busy,done,error, theNodeIdarray, the connection handle) from theTempsection to theStatsection. Recompile. - Locate the
REQinput ofOPC_UA_ReadList. Remove the clock pulse (e.g.,Clock_10Hz,Clock_2Hz). Replace it with the rising-edge expressionNOT stBusy AND NOT stError. - Add
stDoneandstErroracknowledgement logic immediately after the call so the single-cycle pulse is consumed. - Validate the NodeId strings. Open the server in UA Expert (or the manufacturer's configuration tool) and copy the exact
ns=2;s=Channel1.Valuestring. Paste it into thestNodeIds[i].NodeId.Identifiertag. Confirm thatNamespaceIndexmatches what the server returns fromGetEndpoints. - If
OPC_UA_MethodCallis also used, verify that the precedingOPC_UA_MethodGetHandleListsupplies validObjectIds; the Siemens help explicitly warns that an invalid ObjectId here surfaces asBadNodeIdUnknownon the next method call. - Re-download the project and observe the
Status,Diagnostics.Status, andsubFunctionStatustags with a watch table. The client should now run continuously without the 30-second stall.
6. SCL Variable-Scope Pitfalls
The most common SCL error in OPC UA client code is mis-scoping the block's local tags. TIA Portal groups the FB interface into three sections: Input, Output, InOut, Static, and Temp. Only Static and Temp are local memory inside the FB instance DB.
| Section | Lifetime | Use for OPC UA |
|---|---|---|
| Input | Caller supplies each call | REQ (driven by caller's logic) |
| Output | Caller reads after call | None - prefer Stat + InOut |
| InOut | By-reference, persists | NodeId array, ReadResults buffer |
| Static | Persists in instance DB | Busy/Done/Error latches, handles, status words |
| Temp | Reset to 0 each call | Loop counters, scratch pointers only |
If you observe "works for 30 seconds then stops," open the FB, switch to SCL view, and search for any of the OPC UA output tags that were accidentally declared TEMP. The compiler does not warn, because TEMP is a perfectly legal declaration; only runtime behaviour reveals the bug.
7. Diagnostic Procedure in TIA Portal
When the failure re-occurs after the corrections above, follow this diagnostic ladder:
- Open an online watch table on the instance DB of the FB that owns the
OPC_UA_ReadListcall. - Force
REQlow and readStatus. IfStatus = 16#8614_0000the client session is broken - re-runOPC_UA_Connect. - If
Status = 16#0000_0000andBusy = FALSE, the next REQ edge should arm the job. If it does not, your edge logic is incorrect. - Inspect
Diagnostics.subFunctionStatus. Common mappings:-
16#8034_0000BadNodeIdUnknown - NodeId invalid on the server side. -
16#8035_0000BadNodeIdInvalid - NodeId syntactically wrong. -
16#801F_0000BadCommunicationError - session or transport broken. -
16#8005_0000BadIdentityTokenRejected - user/token rejected by server.
-
- Use the TIA Portal online diagnostics referenced in the Siemens TIA Portal help to enable the OPC UA client trace. The trace logs every request and response with timestamps and NodeIds.
8. Verification Checklist
| Check | Expected | Method |
|---|---|---|
| Busy latches | TRUE while a job is in flight, FALSE otherwise | Watch table on instance DB |
| Done pulse | TRUE for exactly one cycle on success | Watch table, OB1 cycle = 2 ms |
| Error pulse | TRUE for exactly one cycle on failure | Watch table |
| Status | 16#0000_0000 idle, 16#7000 transient, 16#8614 fault | Watch table |
| subFunctionStatus | Non-zero only when Status indicates a fault | Watch table |
| Server-side logs | ReadRequest matches exactly the configured NodeId | Server's UA Expert or vendor log |
| 30-minute soak | No stall, no BadNodeIdUnknown | Trend Status over 30 minutes |
9. OPC UA Read Service - Background
For engineers extending the client, the OPC UA specification Part 4 §5.11.2 Read defines the wire-level request and response. Each ReadRequest carries an array of ReadValueId; the response carries a parallel array of DataValue and a parallel array of StatusCode. A non-zero StatusCode at index i means the read of NodeId i failed; the rest of the response may still be valid. The Siemens OPC_UA_ReadList collapses this into the ReadResults output array plus the global Diagnostics.subFunctionStatus.
Per Part 4 §7, services accept named parameters that the client may pass for diagnostics or auditing. Use these parameters when integrating with auditing systems that need a correlation ID per read.
10. Alternative Read Strategies
-
Subscription instead of polling. If the polled value changes frequently, replace
OPC_UA_ReadListwithOPC_UA_CreateSubscription,OPC_UA_AddMonitoredItems, andOPC_UA_PublishingEnable. The server pushes only changed values, eliminating the 30-second poll window entirely. - Server-side aggregation. Use the OPC UA Historical Access (H_Aggregate) service to read pre-aggregated values over a time window instead of polling every cycle.
- Cyclic publish on the server. Many PLC-based OPC UA servers (including the SIMATIC S7-1500 server) expose a "cyclic read" mode that buffers values locally and publishes them on subscription; offload the polling logic to the server.
11. Common Pitfalls and Edge Cases
-
Optimised block access. If the FB instance DB is set to "optimised block access," the
OPC_UA_ReadListcall works only with symbolic addresses. Absolute addressing to the NodeId array will return zeroes. -
Handle reuse across calls. The session handle returned by
OPC_UA_Connectis bound to the FB instance. Re-declaring it asTEMPwill cause a re-connect every cycle, exhausting server resources and producing intermittentBadNodeIdUnknown. -
String lifetime. The
NodeId.Identifierfield is a STRING. If the source STRING is overwritten (e.g., by a ring buffer), the OPC UA runtime still uses the original pointer until the next REQ. Keep the source buffer in a STAT or global DB. -
Multiple FBs sharing one session. When several FBs call
OPC_UA_ReadListagainst the same server, share the session handle and serialise the REQ lines with a token ring; otherwise you will seeStatus = 16#7000warnings. -
Certificate trust. The first connect prompts for trust on the server side. If you rebuild the PLC project with a new CPU serial number, the trust store on the server rejects the new certificate and
OPC_UA_ReadListreturnsBadCommunicationErroron the very first read.
12. FAQ
Why does my OPC_UA_ReadList stop reading after exactly 30 seconds?
A free-running clock pulse combined with a TEMP-scoped busy or NodeId variable causes the request to corrupt when the PLC stack frame rotates. Switch to edge-triggered REQ := NOT busy AND NOT error and move persistent tags to the Static section.
What does Diagnostics Status 16#8614 with subFunctionStatus 16#8034_0000 mean?
16#8614 is the Siemens wrapper status for an internal OPC UA client error; 16#8034_0000 is the OPC UA standard code BadNodeIdUnknown. The server rejected the Read because the NodeId string or namespace does not exist in its address space.
Is Status 16#0000_7000 a fault?
No. It is a transient warning that the client instruction could not accept a new REQ because a previous job is still active. Wait one cycle and re-check Busy. It should not trigger an alarm.
Can I poll at OB1 cycle (1-2 ms) with OPC_UA_ReadList?
Yes, but only if the server can keep up. Drive REQ from NOT busy AND NOT error and add a small debounce timer if the server returns BadResourceUnavailable. For high-rate data, switch to an OPC UA Subscription with Monitored Items.
Why does moving #busy from TEMP to STAT fix the first failure but the error returns later?
Moving #busy alone fixes the latching, but the NodeId array is typically still in TEMP and gets corrupted when the stack rotates. Move the NodeId array, the connection handle, and the result buffer to Static as well.
Does OPC_UA_MethodGetHandleList need valid ObjectIds?
Yes. The Siemens help explicitly notes that OPC_UA_MethodGetHandleList does not validate ObjectIds; supplying an invalid one causes the subsequent OPC_UA_MethodCall to return BadNodeIdUnknown.
Which TIA Portal version is required?
The OPC UA client instructions described here are available in TIA Portal V17 and later. The diagnostics page linked above is from the TIA Portal V20 cloud help; if you are on V17 or V18, use the local help for the same instructions.