Resolving BadNotReadable StatusCode on SINUMERIK 828D OPC UA

David Krause19 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

Problem Overview

When connecting a custom OPC UA client (for example, the Siemens Simple OPC UA Client sample published as support entry 42014088) to a SINUMERIK 828D HMI to read machine axis positions (X, Y, Z) and NC R parameters, engineers frequently see the connection establish, certificates trust correctly, and then every Read call return the StatusCode BadNotReadable (hex 0x80040000). The exact same variables are readable with Siemens OPC Scout V10 on the same PC, which proves the server is healthy and the data exists - the problem is on the client side, in the session's access level, or in the variable identifier format.

This article provides a systematic procedure to diagnose and resolve BadNotReadable on the SINUMERIK 828D OPC UA server, covering user account provisioning, the OPC UA access right, namespace index selection, variable identifier syntax, security policy negotiation, and per-operation read limits.

Understanding the BadNotReadable StatusCode

BadNotReadable is defined in OPC UA Part 4 (Services) of the OPC UA specification. It is one of the most commonly returned result codes in field installations and is often misdiagnosed.

Attribute Value
Hex value 0x80040000
Symbolic ID BadNotReadable
Severity bits 0x80 (Bad)
Sub-code 0x00040000
Definition "The level of access does not allow reading the value"
Specification OPC UA Part 4, Section 7.2 (StatusCodes)

The semantics are precise: the server received the request, resolved the NodeId to a real node in the address space, evaluated the current session's AccessLevel for that node, and determined the session cannot read. The status is not the same as BadNodeIdUnknown (0x80340000) - that would mean the NodeId itself does not exist. BadNotReadable means the NodeId is valid but the session is not authorised for it.

Note: The OPC UA AccessLevel attribute on a node is the intersection of (a) the static access rights the node was published with and (b) the rights granted to the active user identity. If either side is missing, the read returns BadNotReadable. On the SINUMERIK 828D, the second factor - user rights - is the most common failure point.

SINUMERIK 828D OPC UA Server Architecture

The 828D HMI embeds an OPC UA server that exposes NC, PLC, and HMI variables. The server's exact capabilities depend on the software version (the OPC UA server is available from software version 4.5 SP2 onwards; subsequent versions added features such as method calls and additional node types). Check the release notes for your installed version in the Siemens Industry Online Support portal.

Endpoint and Transport

Parameter Value / Format
Default endpoint URL opc.tcp://<HMI_IP>:4840
Default TCP port 4840 (configurable in SINUMERIK Operate)
Security policies offered None, Basic128Rsa15, Basic256, Basic256Sha256
User token types offered Anonymous, UserName (certificate optional)
Server certificate Self-signed by the 828D HMI at first start
Session timeout (default) 60 - 120 seconds (server-configurable)

Namespace Layout

The OPC UA server exposes multiple namespace indices. Indices 0 and 1 are reserved (server-local and OPC UA foundation). Application-specific namespaces start at index 2. The SINUMERIK 828D application namespace index varies by software version - it is typically 4 on current releases, but the only reliable way to confirm is to read the server's namespace array in OPC Scout V10 (Server -> Namespace Array) and note the index that maps to the SINUMERIK 828D application URI.

Critical: The application namespace URI on the 828D is generated per device, not a public string. Always copy it from OPC Scout V10. Do not hard-code it from documentation - it can change after a software update.

Root Cause Analysis

When the connection succeeds but every read returns BadNotReadable, the cause is almost always one of the following. The list is ordered by frequency observed in field support cases.

  1. Anonymous session on a node that requires an authenticated user. The 828D OPC UA server returns R parameters and axis data only to sessions that present a valid UserName identity with the OPC UA access right. Anonymous sessions are denied, and the server surfaces this as BadNotReadable rather than as a more specific security error.
  2. User account exists but lacks the OPC UA access right. The user is in the SINUMERIK user list, the password is correct, and ActivateSession succeeds - but the user has not been granted the "OPC UA" access level. The session is technically open but has no read rights on the protected nodes.
  3. Wrong namespace index in the NodeId. The custom client is sending ns=0;s=... or ns=2;s=... when the data is in ns=4. The server may return BadNodeIdUnknown for the wrong index, or BadNotReadable if the wrong index happens to point at a restricted node.
  4. Wrong variable identifier syntax. SINUMERIK identifiers follow a specific path grammar (forward slashes, bracket indices, exact case). Trailing slashes, wrong bracket direction, or wrong capitalisation make the node unresolvable.
  5. Security policy / mode mismatch. The client requires Basic256Sha256 + SignAndEncrypt but the server offers only None. The session may complete in a degraded mode that returns BadNotReadable for some or all nodes.
  6. Per-operation read limit exceeded. The client requests a batch larger than the server's per-Read cap (often 64 - 256 items on Siemens stacks). The first N items succeed; the rest return BadNotReadable.

Prerequisites

Before changing any client code, confirm the following.

  • The PC and the SINUMERIK 828D HMI are on the same subnet and respond to ping. Note the exact HMI IP address.
  • OPC Scout V10 is installed and successfully reads the target variables (R parameters and axis positions) with a known-good user. Keep OPC Scout V10 open during troubleshooting.
  • You have administrator credentials for the 828D HMI to add or modify users in SINUMERIK Operate.
  • The Simple OPC UA Client sample from Siemens support entry 42014088 is loaded in your development environment.
  • The 828D software version is recorded. OPC UA server availability and node structure depend on the version; consult the SINUMERIK 828D commissioning manual for your release.
  • The OPC UA server is enabled on the 828D. In SINUMERIK Operate, navigate to Setup -> Network -> OPC UA and confirm the server is switched on and the port matches the client configuration (default 4840).

Solution 1 - Configure the SINUMERIK OPC UA User Account

This is the single most common root cause. The 828D has two layers of access: a general access level (User, Service, Manufacturer) and an explicit OPC UA access right. Both must be granted.

Step 1: Create the user on the 828D HMI

  1. On the 828D HMI, navigate to Setup -> User Administration. On older releases the path is HMI -> User Login.
  2. Log in with an administrator account. The default commissioning user is manufact with password SUNRISE - change this in production.
  3. Select Create new user. Use a name without special characters, for example opcua_client.
  4. Assign an access level of at least Service if you need write access. For read-only access to NC variables, the User level plus the OPC UA right is normally sufficient.
  5. Set a strong password that satisfies the SINUMERIK password policy (minimum length, mixed character classes, not recently reused).
  6. Confirm the user is listed and enabled. Some 828D versions require an explicit Activate step on a freshly created user.

Step 2: Grant the OPC UA access right

Beyond the general access level, the OPC UA server has a dedicated right that must be turned on for the user.

  1. In Setup -> User Administration -> Access Levels, locate the user created in Step 1.
  2. Enable the OPC UA access right. The exact label is "OPC UA" or "Remote access via OPC UA" depending on software version.
  3. If separate Read and Write rights exist, enable at least OPC UA Read. Enable OPC UA Write only if the application must write back.
  4. Save and re-authenticate on the HMI to confirm the new rights are active.
Critical: If the OPC UA access right is not granted, the client can establish a session and the server accepts the credentials, but every read of an NC variable returns BadNotReadable. This is by design - the server does not leak information about which right is missing; it reports only that the access level is insufficient. Many integrators stop at the general access level and never see the separate OPC UA switch.

Step 3: Bind the user in the custom client

In the Siemens Simple OPC UA Client sample (and any compliant OPC UA client), the user identity is passed to ActivateSession, not to CreateSession. A common implementation error is to call CreateSession with the user identity and ActivateSession anonymously, which leaves the session effectively anonymous.

// C# pseudo-code aligned with Siemens example 42014088 (OPC Foundation .NET Standard stack)
var session = await Session.Create(
    configuration,
    new ConfiguredEndpoint(endpointDescription),
    certificateValidator: null,
    userIdentity: new UserIdentity("opcua_client", "YourPassword"),
    preferredLocales: null);

After session creation, verify the session is in state SessionState.Activated and that session.Identity reports the user identity you passed. If the client silently falls back to Anonymous on a failed activation, reads will return BadNotReadable for protected nodes.

Solution 2 - Use the Correct Variable Identifier Format

Even with a valid authenticated session, an incorrect variable identifier causes the read to fail. The "Variable Identifier" field in the Siemens sample is a NodeId string, not a free-form label.

NodeId syntax

An OPC UA NodeId is written as ns=<namespace_index>;s=<string_identifier>. The ns value is the namespace index, not the namespace URI. To convert URI to index, read the server's namespace array.

Typical SINUMERIK 828D identifiers

The following table lists representative identifier strings for common targets. The exact spelling depends on the installed software version - verify each one in OPC Scout V10 before committing to the client configuration.

Data Representative identifier (verify in OPC Scout V10)
R parameter 1 ns=4;s=R[1] (path may be /NC/R[1] on some versions)
R parameter 5 ns=4;s=R[5]
Axis X actual position (machine axis) ns=4;s=/Channel/MachineAxis/aaPos[X]
Axis Y actual position ns=4;s=/Channel/MachineAxis/aaPos[Y]
Axis Z actual position ns=4;s=/Channel/MachineAxis/aaPos[Z]
Axis actual feedrate ns=4;s=/Channel/MachineAxis/aaFeedRate
Spindle actual speed ns=4;s=/Channel/Spindle/aaSpeed
Important: The exact path strings depend on the SINUMERIK 828D software version. Do not copy the strings above blindly. Use OPC Scout V10 - which is already working for the target user - to drag the variable into the DA View pane, read the value, and copy the NodeId exactly as the server returned it.

Procedure to capture verified NodeIds

  1. Open OPC Scout V10 and click Connect. In the endpoint picker, choose the same endpoint URL the custom client will use.
  2. Authenticate as the new OPC UA user. The server reveals access-controlled variables only after a successful session.
  3. Browse the address space. For the 828D, useful starting points are Server -> Channel 1 for NC variables and Server -> Axes for machine axis data.
  4. Drag the leaf node (for example, the R-parameter leaf or the X-axis position leaf) into the DA View pane and confirm the read returns a real value with StatusCode Good.
  5. Right-click the read item and choose Copy NodeId. The clipboard will contain the full ns=<i>;s=<path> string.
  6. Paste the NodeId into the custom client's "Variable Identifier" field, character for character.

Solution 3 - Match the Endpoint and Security Policy

A mismatch between client and server security policies can cause the session to be created in a degraded mode that has no read access. The fix is to enumerate the server's endpoints and pick one the client can actually support.

Step 1: Enumerate server endpoints in OPC Scout V10

  1. In OPC Scout V10, on the Connect dialog, click Show Endpoints (or the equivalent "Select Endpoint" button) before clicking Connect.
  2. Record every endpoint URL, SecurityPolicy URI, SecurityMode, and UserTokenType the 828D offers.

Step 2: Match the client configuration

Configure the custom client to connect to one of the endpoints recorded above, using the exact same combination of:

  • Security policy URI (for example, http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256)
  • Security mode (None, Sign, SignAndEncrypt)
  • User token type (Anonymous, UserName)
Recommendation: For initial troubleshooting, set the security policy to None and the user token type to UserName. This isolates access-control issues from transport-security issues. Once the read succeeds, harden the configuration with Basic256Sha256 + SignAndEncrypt for production and load the proper X.509 certificates on both sides.

Solution 4 - Respect the Client Operation Limit

Many OPC UA clients submit Read calls in batches. The Siemens OPC UA server stack enforces a per-operation cap on the number of items per Read or Monitor call (commonly 64 - 256 items, with lower caps on monitored items in some versions). If the client exceeds the cap, the server returns BadNotReadable for the surplus items, which can look like a random access failure.

Symptom pattern

Reads succeed for the first N items in the batch and fail for the remainder, all with BadNotReadable. Reading the same items individually (one NodeId per Read) succeeds for every item.

Resolution

  • Lower the maximum number of variables per Read/Monitor operation in the client. 64 is a safe starting point for many Siemens OPC UA server configurations.
  • In the Siemens Simple OPC UA Client sample, look for a setting named MaxItemsPerRead, MaxPerOperation, or similar. Lower it to 64 and re-test.
  • If no configuration is exposed, issue smaller Read calls in your application code. The OPC Foundation .NET Standard stack exposes this limit through the session's OperationLimits.

Step-by-Step Integration Procedure

This procedure combines the four solutions above into a single reproducible workflow that ends with the custom client reading R parameters and axis positions from the 828D.

Step 1: Verify connectivity

  1. From the PC, ping the 828D HMI IP. Confirm reachability.
  2. Open a TCP connection to the OPC UA port to confirm the server is listening:
    telnet <HMI_IP> 4840
    The connection should open without "connection refused".
  3. In SINUMERIK Operate, confirm the OPC UA server is enabled (Setup -> Network -> OPC UA) and the port matches.

Step 2: Create the user and grant OPC UA access

Follow Solution 1: create the user, set a strong password, and enable the OPC UA access right. Re-authenticate on the HMI to apply the new rights.

Step 3: Capture verified NodeIds with OPC Scout V10

  1. Open OPC Scout V10, click Connect, pick an endpoint, and authenticate as the new user.
  2. Browse to each target variable (R[1], R[5], axis X, axis Y, axis Z).
  3. For each target, drag the leaf node into the DA View and read the value once. Confirm StatusCode Good.
  4. Right-click the read item and copy the NodeId. Keep a record of the namespace index, the namespace URI, and the string identifier for each variable.

Step 4: Configure the Simple OPC UA Client sample

  1. Open the project from Siemens support entry 42014088 in Visual Studio.
  2. Set the endpoint URL to opc.tcp://<HMI_IP>:4840.
  3. Set the user identity to the username and password created in Step 2.
  4. For initial testing, set the security policy to None and the user token type to UserName.
  5. Set the namespace index to the value captured in Step 3 for the SINUMERIK 828D application namespace.
  6. For each variable, paste the verified NodeId into the "Variable Identifier" field.
  7. Set the maximum items per Read operation to 64.

Step 5: Read and verify

  1. Build and run the sample.
  2. Read each variable. The response StatusCode must be Good (0x00000000), and the value field must contain the current value from the 828D.
  3. Cross-check one value with OPC Scout V10 to confirm parity.

Verification

To confirm the issue is resolved, perform the following checks.

  • Every variable in the client returns StatusCode Good (0x00000000) on read.
  • The values match what OPC Scout V10 displays and what the SINUMERIK HMI shows for the same variables.
  • R parameter reads return the current R-parameter value from the NC; updating an R parameter on the HMI is visible to the client within one poll cycle.
  • Axis position reads return the current actual position, updated in real time when the machine moves the axis.
  • Closing and re-opening the client works without manual certificate re-import (assuming certificates are persistent on the PC).
  • The session survives at least 60 seconds of inactivity; if the server-side session timeout is shorter, the client re-activates the session without returning BadNotReadable.

Troubleshooting Matrix

Symptom StatusCode Likely cause Action
Connection succeeds; every read returns access denied BadNotReadable (0x80040000) Anonymous session on a protected node, or user lacks the OPC UA access right Solution 1: create the user on the 828D, grant the OPC UA access right, authenticate as that user
Reads return "node does not exist" BadNodeIdUnknown (0x80340000) Wrong namespace index or identifier path Solution 2: copy the verified NodeId from OPC Scout V10
First N items in a batch succeed; the rest fail with BadNotReadable BadNotReadable (0x80040000) Per-operation read cap exceeded Solution 4: lower MaxItemsPerRead to 64; read in smaller batches
Session activation fails with bad identity BadIdentityTokenRejected (0x80200000) Username does not exist on the 828D, wrong password, or user disabled Verify the user is in the SINUMERIK user list, enabled, and the password matches
Connect fails at TCP level (no OPC UA session) n/a (no StatusCode) Port 4840 blocked by firewall, wrong IP, or OPC UA server disabled on the 828D Check Windows firewall, verify IP with ping, enable OPC UA server in SINUMERIK Operate
Connect fails after TLS handshake BadSecurityChecksFailed (0x80130000) Server certificate not trusted, wrong hostname, or expired Add the server certificate to the client's TrustedPeers store; verify the certificate Subject/SAN matches the HMI IP; regenerate the certificate on the 828D if expired
Read returns Good but value is always the default (0 or empty) Good (0x00000000) Identifier points to a different variable than intended Solution 2: re-verify the NodeId by drag-and-drop in OPC Scout V10; ensure the namespace index matches the application's namespace, not the OPC UA base namespace
Read works once, then fails after a few minutes of inactivity BadSessionIdInvalid (0x80270000) or BadNotReadable Server-side session timeout expired; client did not re-activate Implement session keep-alive in the client (Read call at least every 30 seconds) or re-activate the session on every error
All reads return BadSecureChannelClosed BadSecureChannelClosed (0x80250000) TLS session dropped, often due to network device or aggressive firewall Check managed switches, lower the security mode to None for testing, or implement secure channel renewal in the client

Edge Cases and Field-Proven Caveats

The following behaviours are not obvious from the standard procedure and frequently cost hours during commissioning.

  • Session timeout. The 828D OPC UA server has a server-side session timeout (typically 60 - 120 seconds of inactivity). A long gap between reads causes the next read to return BadSessionIdInvalid or BadNotReadable depending on the server version. Implement a Read-based keep-alive (a Read on any node at half the timeout interval) or re-activate the session on error.
  • Anonymous fallback. Some clients silently fall back to Anonymous if ActivateSession fails. Always inspect session.Identity.DisplayName after activation to confirm the user is the one you passed. Anonymous sessions on a 828D that has the OPC UA access right set to "authenticated users only" produce exactly the BadNotReadable pattern described above.
  • R parameter write access. Reading R parameters works with a basic user, but writing typically requires the Service or Manufacturer access level. If your application needs to write back, escalate the access level on the user.
  • HMI panel login interference. Some 828D versions de-prioritise the OPC UA session when a higher-privilege user is logged in at the HMI panel. Avoid leaving the HMI logged in as manufact while the OPC UA client is running unless that is the intended operational mode.
  • Windows firewall on the PC. Windows Firewall can block outbound OPC UA traffic on port 4840, particularly when the network profile is "Public". If OPC Scout V10 works (often installed with permissive firewall rules) and your custom client does not, add an explicit outbound allow rule for the client's executable on port 4840.
  • Antivirus TLS inspection. Some endpoint security products intercept TLS and break OPC UA certificate validation. If certificate validation fails mysteriously, temporarily disable TLS inspection in the endpoint security product to confirm.
  • Software version dependency. The 828D OPC UA server node structure was reorganised in several software versions. If you upgrade the 828D software, re-capture the NodeIds from OPC Scout V10 - identifiers that worked on the old version may no longer resolve on the new version.
  • Namespace index drift. The application namespace index is not guaranteed to be 4 across all versions. Always read the namespace array from the server (one extra round-trip at session start) and resolve the index dynamically. Hard-coding ns=4 in the client is fragile.
  • Struct DataType handling. Some SINUMERIK 828D nodes expose custom structure data types (for example, axis blocks or tool data). Clients that do not understand the type may return BadNotReadable even when the access right is granted. The Siemens sample at 42014088 uses the OPC Foundation .NET Standard stack, which decodes structures when the type dictionary is available. If your stack does not decode the structure, you may need to enable the relevant DataType node in the server's type dictionary.

FAQ

What does BadNotReadable (0x80040000) mean on a SINUMERIK 828D OPC UA server?

It is the standard OPC UA StatusCode indicating the active session's access level does not permit reading the requested node. On the 828D this almost always means the OPC UA user is not authenticated, the user lacks the dedicated OPC UA access right, or the NodeId resolves to a node the session cannot read.

Why does OPC Scout V10 read successfully but my custom client returns BadNotReadable?

OPC Scout V10 may be authenticating as a user that has the OPC UA access right, or it may be using a connection profile with permissions your custom client does not replicate. Confirm the user identity in both tools, ensure the user exists on the 828D with the OPC UA access right enabled, and pass the same username and password to your custom client at ActivateSession.

How do I find the correct variable identifier for R parameters and axis positions?

Open OPC Scout V10, connect with the same user your custom client will use, browse to the variable in the address space, read it once to confirm access, and right-click to copy the NodeId. Paste the full ns=<i>;s=<path> string into the Variable Identifier field of your client exactly as the server returned it.

Do I need to enable an OPC UA access right separately from the general access level?

Yes. On the SINUMERIK 828D the OPC UA access right is a separate permission that must be granted to the user in addition to the general access level. Without it, the user is authenticated but cannot read OPC UA variables and the server returns BadNotReadable.

My client reads succeed for the first 50 items and fail for the rest with BadNotReadable. What is wrong?

You are exceeding the OPC UA server's per-operation cap. Lower the maximum number of variables per Read call in your client to 64 (a safe default for many Siemens OPC UA servers) and re-test. The surplus items return successfully when sent in smaller batches.

Which namespace index should I use for SINUMERIK 828D variables?

Read the server's namespace array at session start and resolve the index dynamically. The application namespace index is typically 4 on current releases but is not guaranteed across software versions, and the namespace URI is generated per device. Hard-coding the index in the client will break after a software update.

Back to blog