BadAggregateInvalidInputs
BadPart 13 aggregates
BadAggregateInvalidInputs means the server understood your aggregate but could not compute it for that interval: the underlying raw values were Bad, too sparse, or of a type the aggregate cannot handle. Check the raw data for the same window first, then the aggregate configuration's TreatUncertainAsBad and PercentDataGood settings.
What you actually see
A processed read returns good aggregate values for most intervals and this code for a scattered few, usually the intervals covering a machine stop or a comms outage.
Why it happens
- The raw values in the interval are BadAggregates are computed over stored DataValues including their StatusCodes. An interval where the source was disconnected holds values marked Bad, and an aggregate over entirely Bad input has no valid result to return.
- Numeric aggregate applied to a non-numeric nodeAverage, TimeAverage, Total, Delta and StdDev need a numeric data type. Asking for them on a Boolean, a String, an Enumeration or a Structure gives the server nothing to arithmetic over. Count and DurationGood work on any type, which is why they sometimes succeed where Average fails.
- PercentDataGood threshold not metThe aggregate configuration's PercentDataGood sets how much of an interval must be Good for the result to count. An interval only half covered by valid data can fail this threshold and be reported as invalid input rather than returned with a lower quality.
- TreatUncertainAsBad is true and the data is UncertainWith TreatUncertainAsBad set, values carrying UncertainLastUsableValue or UncertainSubstituteValue are counted as Bad for aggregation. An interval of stale-but-plausible readings then produces no aggregate at all, which is the safer behaviour but surprises report authors.
- Processing interval shorter than the sampling cadenceRequesting one-second aggregate intervals over data recorded every thirty seconds leaves most intervals with zero or one raw value. Many aggregates need at least two points inside the interval, so the majority come back invalid.
How to fix it
In diagnostic order: work down, do not skip ahead.
- Read the raw values for one failing intervalTake a single interval that returned the code and do a raw read of exactly that window with returnBounds false. Look at the StatusCode on each DataValue. If they are Bad or Uncertain, the aggregate is behaving correctly and your data quality is the problem.
- Browse the server's AggregateConfigurationUnder the Server object read TreatUncertainAsBad, PercentDataBad, PercentDataGood and UseSlopedExtrapolation. These decide the outcome. Two servers with identical raw data will disagree on the same query if these differ, so record them alongside any report you publish.
- Match the aggregate to the data typeFor counters and Booleans use Count, DurationGood, PercentGood or Delta rather than Average. For analog process values use TimeAverage rather than Average, since TimeAverage weights by duration and is the correct choice for irregularly sampled data.
- Widen the processing intervalSet processingInterval to at least several times the node's recording cadence. For OEE reporting a one-minute or five-minute interval over one-second data gives stable aggregates; a one-second interval over one-minute data cannot work.
- Report quality alongside the aggregateAsk for PercentGood or DurationGood over the same intervals in the same request. Then a failed or thin interval is visible as a quality number in your report rather than as a missing row somebody later fills with a zero.
Where it shows up, by tool and stack
| Tool / stack | What to do there |
|---|---|
| asyncua (Python) | Build ua.ReadProcessedDetails with a processingInterval in milliseconds and one aggregateType NodeId per node. Aggregate NodeIds come from the server's AggregateFunctions folder; browse it rather than hardcoding identifiers. |
| UA-.NETStandard (C#) | The session's HistoryClient exposes processed reads directly. Per-interval statuses arrive inside the returned HistoryData, so iterate them; a single service-level success can contain many invalid intervals. |
| node-opcua | Aggregate support is server-dependent even when the service exists. Browse Server, ServerCapabilities, AggregateFunctions to see the real list before requesting anything, and expect fewer functions than Part 13 defines. |
| UaExpert | Use the plain History Trend View on the same window to see the raw values and their quality colouring. That comparison settles whether the aggregate or the data is at fault in about a minute. |
| Ignition | If your aggregates come from Ignition's historian rather than from the UA server, the interval and quality semantics are Ignition's, not Part 13's. Be explicit about which layer computed a number before comparing two reports. |
What it looks like in the log
HistoryRead processed: interval 2026-09-07T13:20:00Z aggregate=TimeAverage -> BadAggregateInvalidInputs
aggregate config: TreatUncertainAsBad=true PercentDataGood=100 - interval discarded (37% Good)
Confirm the fix
Re-run the processed read with a widened processing interval and an appropriate aggregate, and confirm every interval returns a value with an acceptable PercentGood. Cross-check one interval by computing it yourself from the raw values.
Stop it happening again
Pin the aggregate configuration you rely on, always request PercentGood or DurationGood alongside the value, and choose interval sizes from the node's real recording cadence. Fix the upstream data quality that produces Bad and Uncertain values rather than tuning thresholds to hide 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.