On Ignition 8.3.0-beta4 (build b2025081810, Azul Java 17.0.15), every isAlarmActiveFiltered expression binding in Vision fails on the first evaluation. This includes the unmodified example from the manual. The cause is a platform bug, tracked as IGN-14301: the client-side RPC encoder cannot serialize the filtered-alarm request, so the request never reaches the gateway. Your tag paths, priorities and alarm configuration are not the problem. The fix is targeted for 8.3.1. Until then, move the alarm evaluation off the client RPC path or bind directly to the PLC alarm bits.
Exception chain in the expression binding error
Read the innermost Caused by line first. It is the only line that tells a platform fault apart from a configuration fault. The outer layers are generic wrappers. Error executing expression binding on UDT_Tank.UDT_Tank.ALM_ActiveCritical appears for any binding failure. Error retrieving alarm state from gateway sounds like a connectivity or permissions problem, but it is only the message the alarm function uses to wrap whatever broke beneath it.
The deciding line in this trace is:
java.lang.ClassCastException: class com.inductiveautomation.ignition.common.rpc.impl.AlarmingRpc$IsAlarmActiveFilteredRequest
cannot be cast to class java.io.Serializable
at com.inductiveautomation.ignition.common.rpc.impl.AlarmingRpc$1.encode(AlarmingRpc.java:57)
at com.inductiveautomation.ignition.common.rpc.proto.ProtoRpcSerializer.encodeValue(ProtoRpcSerializer.java:119)
A ClassCastException during encode means the failure happened inside the client JVM while it was building the outbound message. No network round trip took place. A bad path or a gateway-side fault looks different.
| Observed symptom | Innermost cause | Fault class | Action |
|---|---|---|---|
Binding error on template open; trace ends in ClassCastException at AlarmingRpc$1.encode
|
Filtered-alarm request object is not serializable by the 8.3.0 RPC encoder | Platform bug IGN-14301
|
Workaround or upgrade to 8.3.1 |
| Expression rejected in the editor before it runs | Parse error, for example curly quotes pasted from a web page or document | Syntax | Retype the quotes as straight ASCII "
|
| Expression evaluates cleanly but always returns false while the PLC bit is true | Path pattern matches nothing, priority window excludes the alarm, or the alarm is not populated on the gateway | Configuration or gateway alarm state | Check the Alarm Status table and path pattern |
| Binding shows error with a timeout or connection exception at the root | Client lost its gateway session | Communications | Check the gateway connection, not the expression |
Deciding values and where to read them
| Quantity | Failing value | Where to read it |
|---|---|---|
| Gateway version and build | 8.3.0-beta4, b2025081810
|
Gateway web interface status/overview page; Designer Help > About |
| Client Java runtime | Azul 17.0.15 | Designer or client diagnostics console header |
| Innermost exception class |
ClassCastException to java.io.Serializable
|
Full stack trace from the error overlay on the bound property, or the client/Designer console |
| Failing frame | AlarmingRpc$1.encode(AlarmingRpc.java:57) |
Same trace, first frame under the innermost Caused by
|
| Control function result |
isAlarmActive evaluates without error on the same build |
Temporary test property bound to the manual example |
| Last known-good version | 8.1.48 | Existing production gateways running the same template |
The control test is the one that isolates the fault. isAlarmActive uses the same alarming RPC service and passes on the same client and gateway. That rules out session, permission and gateway alarm-subsystem faults. Only the filtered request type is broken.
Client-to-gateway RPC encode path in Vision
Vision clients and the Designer run expression bindings locally in the client JVM. Alarm state lives on the gateway, so an alarm expression function cannot answer from local data. Every evaluation becomes a remote call. The stack trace shows the whole path, in order:
-
VisionTemplate.startupstarts the template's bindings. In this case that happened when the template was double-clicked open in the Designer. -
ExpressionPropertyAdapter.runExpressionevaluates the binding on the custom property. -
ClientFunctionFactory$IsAlarmActiveFilteredFunctionClient.executeis the client-scope implementation of the function. It calls a proxy for the alarming RPC interface. -
GatewayInterface.invokehands the call toProtoRpcSerializer.writeParametersto encode the parameters. -
AlarmingRpc$1.encodecasts theIsAlarmActiveFilteredRequestobject tojava.io.Serializable. It needs that cast to fall back to Java object serialization. The class does not implement that interface, so the cast throws.
The failure is deterministic. It does not depend on load, timing, tag count or alarm state, because the exception fires before a single byte leaves the client. Every binding that calls the function fails on every evaluation. A template with four priority properties produces four identical errors.
The 8.3 line changed how client-gateway RPC messages are encoded. That is why an expression that runs cleanly on 8.1.48 breaks here without any edit to the project. The upgrade exposed a request type that the new encoder was not built to handle.
Version and function scope of IGN-14301
| Condition | Result |
|---|---|
Ignition 8.1.48, custom isAlarmActiveFiltered binding |
Works |
| Ignition 8.3.0-beta4, custom binding | Fails with ClassCastException
|
Ignition 8.3.0-beta4, manual example of isAlarmActiveFiltered
|
Fails identically |
Ignition 8.3.0-beta4, manual example of isAlarmActive
|
Works |
| Fix target | 8.3.1 (acknowledged as a bug in 8.3.0; too late in the release cycle to land in 8.3.0) |
Treat the whole 8.3.0 release as affected unless its release notes list IGN-14301 as resolved. Check the release notes of each 8.3.x build for that ticket number before you revert any workaround.
Workaround procedure for PLC-evaluated alarm UDTs
In this architecture the alarms are evaluated in the Rockwell PLC by an alarm AOI. The UDT exposes four discrete bits: high-high, high, low and low-low. It also carries the process value and setpoints. Each Ignition alarm is a digital alarm on one of those bits. The template then uses one property per priority, each bound to a variant of:
// Check if there is a critical alarm active belonging to the
// analog alarm UDT
isAlarmActiveFiltered({UDT_Tank.UDT_Tagpath} + "*", "*", "*", 4, 4, 0, 1, 0)
The priority window 4, 4 selects Critical only. The trailing three flags control the shelved/acknowledged/unacknowledged filtering. Confirm their order and meaning against the function page in the Ignition manual for your version. You need that meaning to reproduce the same filtering in a workaround.
| Option | Avoids client RPC encode | Keeps shelve/ack filtering | Runs on 8.1.48 and 8.3.0 |
|---|---|---|---|
| A. Bind to the PLC alarm bits in the UDT | Yes, no alarm function called | No | Yes |
| B. Gateway-scope expression member tag in the UDT | Yes, evaluated on the gateway | Yes | Yes, test on 8.3.0 before rollout |
C. Replace with isAlarmActive
|
Uses a request type that encodes correctly | Only what its argument list allows | Yes |
| D. Keep the original expression; hold 8.3 deployment until 8.3.1 | n/a | Yes | 8.1.48 only until upgrade |
Option A — direct bit binding. Use this when the indicator only needs to show whether the PLC condition is active.
- In the UDT definition, find which member bit carries the alarm that is configured at each Ignition priority. The mapping is whatever your alarm configuration sets. Read it from the alarm properties on each bit member rather than assuming high-high is Critical.
- Rebind each template priority property to an indirect tag binding on that member, built from the template's UDT parameter.
- If one priority covers more than one bit, use a boolean OR of those members in an expression binding. Tag references are local reads, not alarm RPCs, so they are not affected by the bug.
Option B — gateway-evaluated member. Use this when shelved and acknowledged alarms must still suppress the indicator.
- Add a Boolean expression member tag to the UDT for each priority, for example one for active Critical.
- Put the same
isAlarmActiveFilteredcall in the member's expression. Build the path from the UDT instance path parameter so it covers that instance's members. - Expression tags execute on the gateway, not through the Vision client's encode path in the stack trace. Before you roll this out, confirm on your 8.3.0 build that the member evaluates without a quality error.
- Rebind the template properties to these members with ordinary tag bindings.
Options A and B both give you one template that runs on 8.1.48 and 8.3.0 gateways without per-version edits. The 8.3 alarm metrics features are the long-term replacement for this pattern. They do not exist on 8.1, so a mixed fleet still needs a version-neutral binding.
Template behavior checks after the change or upgrade
- Open the template in the 8.3 Designer. Confirm that no error overlay or exception dialog appears on any of the four priority properties.
- Launch a real Vision client and repeat the check. The Designer and the client share the client-scope code path, but the launched client is what operators see.
- Force each PLC alarm bit in turn, from the controller or a test routine. Watch only the matching priority property go true, and confirm the other three stay false.
- With a bit active, compare the template indicator against the Alarm Status table filtered to the same UDT instance. A mismatch points to gateway alarm state, not the binding.
- For Option B, shelve and acknowledge an active alarm. Confirm the indicator follows the filter flags the way it did on 8.1.48.
- After you move to 8.3.1, check the build in the gateway status page. Restore the original
isAlarmActiveFilteredbinding on a copy of the template, then repeat steps 1 through 5 before you replace the workaround fleet-wide.
Recurring pitfalls in filtered alarm bindings
-
Curly quotes. Expressions copied from web pages or word processors often carry typographic quotes around
*. The expression parser only accepts straight ASCII quotes. This produces a parse error, which is a different symptom fromIGN-14301. Retype the quotes before you chase anything else. -
Wildcard overreach. Appending
"*"directly to an instance path matches every sibling whose name starts with the same string. For example, a pattern built forTank1also matchesTank10throughTank19. Append the path separator before the wildcard so the pattern only covers that instance's members. -
Misreading the wrapper message.
Error retrieving alarm state from gatewaysends engineers toward gateway network and security settings. On this bug the gateway never receives a request. Trust the innermost exception, not the wrapper. -
Empty gateway alarm state. A separate 8.3 issue,
IGN-14308, covers UDT member alarms that do not always populate when active. If a working binding returns false while the PLC bit is true, check whether the alarm appears in the Alarm Status table at all before you edit the expression. Option A is immune to this because it reads the bit directly. Option B is not. -
Beta builds in production. 8.3.0-beta4 is a pre-release build. Validate alarm templates on a test gateway and keep production on 8.1.48 until the release that fixes
IGN-14301has passed the checks above.
FAQ
Does isAlarmActiveFiltered work in Ignition 8.3.0?
Not from Vision client or Designer scope. Every call, including the manual example, fails with a ClassCastException at AlarmingRpc$1.encode because the request cannot be serialized. The bug is tracked as IGN-14301 and is targeted for 8.3.1.
Can I keep one Vision template that runs on both 8.1.48 and 8.3.0?
Yes. Bind the template properties to the UDT's PLC alarm bits, or to gateway-scope expression member tags that compute the filtered state. Neither approach depends on the broken client RPC path. Plain isAlarmActive also works on both versions, but you lose the priority window filter.
Can I get a fix for IGN-14301 before 8.3.1?
Check each 8.3.x release note for IGN-14301 before you plan around a specific build. If the workarounds do not meet your alarm-handling requirements, or the error persists on a build listed as fixed, stop troubleshooting the project. Open a case with Inductive Automation support and include the ticket number, the gateway build string and the full stack trace.