Status code · Data access

BadNotWritable

BadAccess level

BadNotWritable means the node's AccessLevel or UserAccessLevel does not grant write permission. Read both attributes: AccessLevel is the node's capability, UserAccessLevel is what your identity gets. If AccessLevel allows writing but UserAccessLevel does not, the fix is the user role, not the node.

Defined behaviour: The access level does not allow writing to the node - the attribute is not writable for this user or not writable at all. (our description of the condition this code reports)

What you actually see

A Write returns BadNotWritable immediately, with no delay and no effect on the value, while Reads on the same node work perfectly.

Why it happens

  • The node is genuinely read-only in the modelAccessLevel is a bit mask with CurrentRead and CurrentWrite bits. A node exposing a computed value, a status word or a device identity field typically has CurrentRead only. No client-side change will make it writable; the model has to change.
  • The user identity lacks write permissionUserAccessLevel is AccessLevel filtered by what the current session's identity is allowed to do. An anonymous session very often gets read-only access to nodes that a named user can write. The node looks writable when you inspect AccessLevel and refuses when you write, which is exactly this case.
  • The PLC tag is not marked writable in the server configurationOn PLC-embedded servers, write access is a per-tag or per-block setting in the engineering tool, separate from the OPC UA server being enabled. A block without the writable flag set is exposed read-only regardless of the user.
  • Role permissions deny the write at the Part 18 layerRolePermissions and UserRolePermissions on the node, or on its parent, can deny the Write permission for the roles the session holds. This is enforced independently of AccessLevel, so a node can have CurrentWrite set and still refuse.
  • Wrong attribute targetedWriting to an attribute other than Value - DisplayName, Description or a modelling attribute - is refused on most servers because the address space is not runtime-editable. The code reads as a node problem but is really an attribute-choice problem.

How to fix it

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

  1. Read AccessLevel and UserAccessLevel on the nodeBoth are Byte bit masks carrying CurrentRead and CurrentWrite among others. If AccessLevel has the write bit but UserAccessLevel does not, you have an authorisation problem, not a model problem, and reconnecting anonymously will never fix it.
  2. Reconnect with a named user identityIf you were anonymous, connect with a username and password on an endpoint whose security mode permits it. On the free lab server opc.tcp://milo.digitalpetri.com:62541/milo, user1 with password password is the documented named identity to test with.
  3. Check the node against its type definitionBrowse HasTypeDefinition and look at how the type declares the variable. A companion-specification node that is defined as read-only in the model will be read-only in every conforming server, and asking the vendor to change it is not going to succeed.
  4. Verify write access at the source deviceFor a PLC server, open the engineering project and confirm the tag or data block is published with write access. In many toolchains the OPC UA accessibility flag is per variable and defaults to read-only even when the server itself is enabled.
  5. Look for role permissions on the node and its parentsRead RolePermissions and UserRolePermissions where the server exposes them. Permission inheritance means a deny on the containing Object can block writes to every child variable, which explains a whole folder going read-only at once.
  6. Confirm you are writing the Value attributeThe WriteValue must carry the Value attribute id. A client library that defaults to a different attribute, or a WriteValue copied from a browse operation, produces this code even on a fully writable node.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UaExpertThe Attributes pane shows AccessLevel and UserAccessLevel decoded into readable flags. Comparing the two rows takes a few seconds and immediately separates a model problem from a permissions problem.
asyncua (Python)Read the AccessLevel and UserAccessLevel attributes and compare them before writing rather than catching the fault, so you can log a meaningful reason instead of a bare status code.
node-opcuaRead the AccessLevel and UserAccessLevel attributes with readAttribute and decode the flags. Anonymous sessions against a server with a user manager routinely see a reduced UserAccessLevel.
Siemens S7-1500OPC UA write access is configured per tag or per data block in the engineering project. Also check the server interface definition if one is used - variables not in the interface are not writable through it.
IgnitionA tag bound to a read-only OPC item shows a write error in the gateway log and the tag remains at its previous value. Check the device connection user, since Ignition connects with the credentials on the device connection, not the client's.
KEPServerEXTag client access is a per-tag property set to read only or read/write in the project. It is enforced in the server before the underlying device is touched, so the write fails instantly with no device round trip.

What it looks like in the log

Write ns=3;s=Setpoint failed: BadNotWritable (AccessLevel=CurrentRead, UserAccessLevel=CurrentRead)
ServiceFault: BadNotWritable on attribute Value
Tag write rejected by server - client access is read only

Confirm the fix

Write the node and read it back in the same session. A Good write status is not proof on its own where a server accepts and discards; the read-back value is.

Stop it happening again

Record AccessLevel and UserAccessLevel per node when the integration is commissioned, and re-check them after a PLC download or a server upgrade. Give write-capable clients their own named identity rather than sharing an anonymous connection.

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