Fixing S7-1500 OPC_UA_ReadList Error 8034_0000 BadNodeIdUnknown

David Krause12 min read
OPC / OPC UASiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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.

Scope. This article targets the TIA Portal V20 OPC_UA_ReadList diagnostics page and aligns with the OPC UA specification Part 4 - Services, 5.11.2 Read. Code patterns are valid for S7-1500/S7-1200 G2 firmware V20.x and later client instructions; verify against your local TIA Portal help if you are on V17 or V18.

1. Problem Description

A common S7-1500 OPC UA client implementation fails after roughly 30 seconds of continuous operation. Symptoms observed in the field:

  • #busy remains permanently TRUE after 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_ReadList instance 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:

  1. 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.
  2. Lost acknowledgement: a single-cycle done or error pulse 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 NodeId array was overwritten because of a TEMP-scope variable losing its value at block exit.
  • The NamespaceIndex does 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_MethodGetHandleList instruction was used prior to OPC_UA_MethodCall and provided an invalid ObjectId; the documentation explicitly notes this case as a known cause of BadNodeIdUnknown when the error is observed under OPC_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.

Rule: Every tag whose value must persist across block calls - 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 Error guarantees 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

  1. Open the FB that wraps OPC_UA_ReadList. In the FB interface, move every tag that must persist (busy, done, error, the NodeId array, the connection handle) from the Temp section to the Stat section. Recompile.
  2. Locate the REQ input of OPC_UA_ReadList. Remove the clock pulse (e.g., Clock_10Hz, Clock_2Hz). Replace it with the rising-edge expression NOT stBusy AND NOT stError.
  3. Add stDone and stError acknowledgement logic immediately after the call so the single-cycle pulse is consumed.
  4. Validate the NodeId strings. Open the server in UA Expert (or the manufacturer's configuration tool) and copy the exact ns=2;s=Channel1.Value string. Paste it into the stNodeIds[i].NodeId.Identifier tag. Confirm that NamespaceIndex matches what the server returns from GetEndpoints.
  5. If OPC_UA_MethodCall is also used, verify that the preceding OPC_UA_MethodGetHandleList supplies valid ObjectIds; the Siemens help explicitly warns that an invalid ObjectId here surfaces as BadNodeIdUnknown on the next method call.
  6. Re-download the project and observe the Status, Diagnostics.Status, and subFunctionStatus tags 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:

  1. Open an online watch table on the instance DB of the FB that owns the OPC_UA_ReadList call.
  2. Force REQ low and read Status. If Status = 16#8614_0000 the client session is broken - re-run OPC_UA_Connect.
  3. If Status = 16#0000_0000 and Busy = FALSE, the next REQ edge should arm the job. If it does not, your edge logic is incorrect.
  4. Inspect Diagnostics.subFunctionStatus. Common mappings:
    • 16#8034_0000 BadNodeIdUnknown - NodeId invalid on the server side.
    • 16#8035_0000 BadNodeIdInvalid - NodeId syntactically wrong.
    • 16#801F_0000 BadCommunicationError - session or transport broken.
    • 16#8005_0000 BadIdentityTokenRejected - user/token rejected by server.
  5. 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_ReadList with OPC_UA_CreateSubscription, OPC_UA_AddMonitoredItems, and OPC_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_ReadList call 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_Connect is bound to the FB instance. Re-declaring it as TEMP will cause a re-connect every cycle, exhausting server resources and producing intermittent BadNodeIdUnknown.
  • String lifetime. The NodeId.Identifier field 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_ReadList against the same server, share the session handle and serialise the REQ lines with a token ring; otherwise you will see Status = 16#7000 warnings.
  • 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_ReadList returns BadCommunicationError on 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.

Back to blog