BadOutOfRange
BadValue range
BadOutOfRange means the value is the right type but outside the permitted range: beyond the node's EURange or InstrumentRange, outside an enumeration's defined values, or outside the legal range of a service parameter. Read the node's range properties and clamp before writing.
What you actually see
A Write with a plausible value is rejected while a smaller or larger value on the same node succeeds, and reading the node shows a range property that explains the boundary.
Why it happens
- Value outside EURange or InstrumentRangeAnalogItemType variables carry an EURange Property giving the engineering-unit low and high, and optionally an InstrumentRange giving the raw instrument span. Servers that enforce these reject writes outside them. EURange is also what a Percent deadband is computed against, so a node without it cannot use percent deadbands at all.
- Enumeration value not definedEnumerations travel as Int32, so any integer encodes cleanly. A value that is not one of the defined EnumStrings or EnumValues entries is out of range rather than a type error, which is why it passes type checking and then fails.
- Numeric overflow for the declared widthA value that exceeds what the node's DataType can represent - 40000 into an Int16, a negative into a UInt - is out of range. Some servers report this as a type mismatch instead, so both codes should be considered together.
- Service parameter outside its permitted rangeNot every occurrence is about a variable. A negative sampling interval other than -1, an out-of-bounds MonitoringMode, a priority outside the byte range, or an invalid TimestampsToReturn value produce this code from a service call rather than from a value write.
- Device rejects the value even though the model allows itA PLC-embedded server may pass the write to the device, which enforces its own limits. The OPC UA model shows a wide EURange while the control logic clamps to a narrower operating window, so the rejection comes from below the server.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Read the node's range propertiesBrowse HasProperty from the variable and read EURange and, where present, InstrumentRange. EURange is a structure with Low and High. Also read EngineeringUnits to be sure you are working in the units the server expects.
- Check the enumeration definition before writing an enumRead EnumStrings or EnumValues from the DataType node, or the DataTypeDefinition, and write only a defined value. Do not assume the enumeration is contiguous from zero.
- Clamp on the client and report the clampClamp to the published range rather than letting the write fail, but log the clamp. Silently clamping hides a scaling or unit error upstream, which is usually the real defect.
- Check units and scalingAn out-of-range value is frequently a unit mismatch - bar written where the node expects kPa, or a raw count written where the node expects engineering units. Compare EngineeringUnits against what the source is producing before adjusting the range.
- If it came from a service call, inspect the parametersFor subscription and monitored item failures, check SamplingInterval, QueueSize, Priority, MonitoringMode and TimestampsToReturn. A sampling interval of -2 or a TimestampsToReturn outside the defined set produces this code with nothing to do with any variable.
- Confirm at the device where the server is a PLCIf EURange permits the value and the write still fails, check the PLC logic for its own limit handling. The server is relaying a device rejection.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| UaExpert | The Data Access View shows engineering units and range for AnalogItemType nodes, and the Attributes pane lists the EURange Property. Comparing the value you intend to write against that row takes seconds. |
| asyncua (Python) | Read the EURange property via node.get_child(['0:EURange']) and inspect Low and High. asyncua does not clamp for you, so range enforcement is the server's or yours. |
| node-opcua | The client reads EURange and EngineeringUnits as properties of the analog item. opcua-commander renders them as a range and a unit alongside the value, which is a quick way to see the boundary. |
| opcua-commander | Displays engineering units and the EURange next to the value, for example a value in degrees Celsius with its range in brackets. That view answers the range question without any client coding. |
| Siemens S7-1500 | Range checks in the PLC program can reject a write that the OPC UA model permits. The status comes back from the server, but the decision was made in the control logic - check the block, not the server settings. |
| Ignition | Tag writes that violate a device or server range fault in the gateway log with the returned status. Ignition's own tag scaling can also be the cause - confirm whether the scaling is applied on the tag or expected by the server. |
What it looks like in the log
Write 150.0 to ns=3;s=Tank.Level rejected: BadOutOfRange (EURange 0.0 to 100.0)
ServiceFault: BadOutOfRange - SamplingInterval -5 is not a legal value
Enumeration value 7 is not defined for DataType ns=4;i=3001
Confirm the fix
Write a value inside the published range, read it back, and confirm both the value and its engineering units. If the read-back differs from what you wrote, the server or device is scaling and the range is not the whole story.
Stop it happening again
Read EURange and EngineeringUnits at commissioning and store them with the tag definition, then validate on the client before writing. Where a percent deadband is planned, confirm EURange exists on the node first, because percent deadbands depend on it.
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.