Acknowledgement succeeds after the client passes the selected alarm's current EventId as a valid ByteString. For the affected Prosys graphical client 3.x releases, the primary branch is a client-side mapping defect, not an SDK or server fault. If another client also fails, test whether the selected event has already been replaced by a newer alarm occurrence.
Initial acknowledgement decision path
- Reproduce the failure by selecting the current event, opening its context menu, and invoking Acknowledge. Record the complete status. The relevant failure is
Bad_EventIdUnknown (0x809A0000), reported as “The specified event id is not recognized.” Do not move on until the status code is captured rather than inferred from the dialog title. - Read the per-argument results. In the reported case, both entries were
GOOD (0x00000000). This means the call arguments passed basic argument-level validation; it does not mean that the server recognized the event instance represented by the supplied identifier. - Repeat the acknowledgement against the same server with a client known to preserve the event identifier correctly, such as UaExpert. If that call succeeds, follow the client-mapping branch. If it fails with the same status, follow the event-freshness branch.
- Repeat the test using the newest event occurrence for the alarm. If the current event succeeds while an older event fails, the server has advanced to a new alarm instance and no longer recognizes the older identifier.
| Reading | Meaning | Next check |
|---|---|---|
Bad_EventIdUnknown (0x809A0000) only in the Prosys graphical client 3.x |
The selected identifier is being lost or changed in that client | Inspect the ByteString mapping path |
| Same server accepts the call from UaExpert | The server and alarm method can process a valid identifier | Correct or replace the affected client |
| Multiple clients reject an older occurrence | The stored event is stale relative to the active alarm | Select the newest event and retry |
Both InputArgumentResults are GOOD
|
Argument syntax passed, but semantic event lookup failed | Compare the transmitted identifier with the received event |
Event identifier integrity check
An OPC UA alarm acknowledgement targets a particular event occurrence, not merely the alarm source shown in the user interface. The server uses EventId to locate that occurrence. A null, altered, or obsolete value therefore produces Bad_EventIdUnknown even when the selected row still looks valid.
- Capture the
EventIdwhen the event notification arrives at the client. Record its data type, null state, length, and byte content without converting it to text. - Capture the value immediately before the acknowledgement method call. Compare it byte for byte with the received value.
- If the outgoing value is null or differs, stop server-side troubleshooting. Trace the client model, table-row storage, context-menu selection, and method-call conversion until the same bytes reach the call.
- If the values match, check whether a newer event for the same alarm arrived between selection and acknowledgement. Continue with the freshness check.
A displayed alarm row is not proof that its identifier remains usable. Sorting, refreshing, or reusing a row object can separate the visible event fields from the binary identifier retained for the method call. Keep the identifier attached to the exact received event record.
Client and server isolation
The reported fault appeared with SampleConsoleServer and with a custom OPC UA server, while the common component was the Prosys OPC UA Client graphical application. That pattern points to the caller before it points to either server implementation.
- Connect UaExpert and the affected graphical client to the same server.
- Wait for one new alarm occurrence and select that occurrence in both clients.
- Acknowledge it first from one client. For a clean comparison, generate another occurrence before testing the second client; acknowledgements change alarm state and can invalidate a direct second attempt.
- If UaExpert succeeds and the Prosys graphical client returns
0x809A0000, classify the fault as client-specific. If both fail on fresh occurrences, inspect the server's event retention and method handling.
Testing two server applications is also useful. The same failure across SampleConsoleServer and a custom server reduces the probability of a server-specific implementation error. A successful independent-client test then completes the isolation.
Version 3 mapping mechanism
SDK version 3 changed the UA ByteString mapping from byte[] to a concrete ByteString class. The graphical client was not updated correctly for that change in its 3.x versions. During acknowledgement, it resolved EventId as a Null NodeId; the server consequently received no recognizable event identifier and returned Bad_EventIdUnknown.
| Layer | Expected value | Faulted value or effect |
|---|---|---|
| Event notification | Binary EventId
|
Valid event can still appear in the graphical list |
| SDK version 3 mapping | Concrete ByteString
|
Legacy byte[] handling no longer matches |
| Graphical acknowledgement path | Original event bytes |
EventId resolves as Null NodeId
|
| Server lookup | Recognized current event | Bad_EventIdUnknown (0x809A0000) |
This distinction matters when a custom application uses the SDK. The SDK type change itself is not the acknowledgement defect. Application code must store and forward the concrete ByteString without applying obsolete array assumptions or converting it through a node-identifier field.
Resolving branches
- For the Prosys graphical client 3.x branch, use UaExpert for acknowledgement testing or install an application release containing the planned graphical-client correction. Changing the server does not repair the client conversion path.
- For a custom SDK version 3 client, change the event-record field and method-call preparation to retain the received concrete
ByteString. Remove any path that expectsbyte[]or resolves the event value as aNodeId. - For the stale-event branch, refresh the alarm view, select the newest occurrence, and invoke Acknowledge again. Do not retry a cached row after the server has published a replacement event.
- For an unresolved server-side branch, log the received identifier at the method boundary and compare it with the identifiers currently retained by the alarm subsystem. A matching fresh identifier shifts the investigation to server event-state handling; a mismatch returns it to the client or transport-side data path.
Acceptance verification
- Generate or wait for a new alarm occurrence and capture its
EventId. - Acknowledge that exact occurrence from the corrected or alternate client.
- Confirm that the method call returns a successful overall status, not merely
GOODentries inInputArgumentResults. - Confirm that the server reports the alarm as acknowledged.
- Generate a second occurrence and repeat the test. Compare the newly received and transmitted identifiers byte for byte to prove that the repair handles changing event instances rather than one cached value.
FAQ
What happens if InputArgumentResults are GOOD but acknowledgement fails?
GOOD (0x00000000) for both arguments means basic argument validation passed. The overall Bad_EventIdUnknown (0x809A0000) still means the server could not associate the supplied identifier with a recognized event.
What happens if I acknowledge an old OPC UA alarm?
If a newer alarm occurrence has replaced it, the server may no longer recognize the older EventId. Refresh the view, select the newest occurrence, and retry with its identifier.
What happens if UaExpert works but the Prosys client fails?
That result isolates the failure to the graphical client's acknowledgement path. In the affected 3.x versions, the SDK mapping changed from byte[] to ByteString, and the application resolved the event identifier incorrectly.
What happens if the ByteString mapping is corrected?
The client should pass the received EventId unchanged and the server should accept the current occurrence. Verify the repair by acknowledging two newly generated events and comparing each received identifier with the value transmitted in its method call.