You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
alert_transitions API returns incomplete transitions (raises missing) #1155
POST /api/v2/spaces/{spaceId}/rooms/{roomId}/alert_transitions returns only part of the alert transitions in the requested window. Transitions into WARNING/CRITICAL are missing far more often than transitions back to CLEAR, so any count of "alerts raised" built on this endpoint undercounts, and raise/clear pairs cannot be matched.
Evidence
Same space and room, same time windows, payload { "after": <s>, "before": <s> } (no node or chart filters):
Window
Source
Result
last 3h
alert_transitions (frontend endpoint)
1,098 transitions in the room; for all azure_monitor.* alerts together: CLEAR→CRITICAL 5, CRITICAL→CLEAR 15, CLEAR→WARNING 9, WARNING→CLEAR 12
last 3h
MCP get_alert_transitions, one single azure_monitor.* alert
36 transitions for that alert alone: CLEAR→CRITICAL 18, CRITICAL→CLEAR 18
last 24h
alert_transitions (frontend endpoint)
6,942 transitions in the room; for azure_monitor.* alerts: CLEAR→CRITICAL 7 vs CRITICAL→CLEAR 27, CLEAR→WARNING 10 vs WARNING→CLEAR 43
One alert alone has more raises in 3 hours than the endpoint returns for all alerts of that collector, and in every window the endpoint returns many more clears than raises.
Other observations
The response has no old.duration, so time spent in the previous state cannot be read directly.
Adding an unsupported contexts field to the payload changes the result to a 100-row, unfiltered response instead of being ignored or rejected.
Expected
All transitions in the window are returned (or the response says it is truncated and supports paging), and request fields that are not supported are rejected or ignored without changing the result.
Impact
Frontend cards that count raised alerts over a time range (alerts raised over time, raised/resolved counts, mean time to resolve, noisiest resources) undercount, especially for flapping alerts.
Fixed and deployed. The endpoint now returns every transition in the window, newest first. It pages them and reports a total, and each row now includes old.duration.
Why raises were missing
A history response merged two sources:
Feed events: only the newest 100, whatever the window, because of feed-svc's lean search page cap.
Current state: one row per alert instance from node_instance_alarms, presented as a transition.
Most instances are CLEAR at any given moment, so the second source was mostly →CLEAR rows, including UNKNOWN→CLEAR initialisations. A flapping alert showed up once, as its last clear. That is how 3h returned 1,098 rows with only 5 CLEAR→CRITICAL. On staging the endpoint covered 119 of 322 transitions over 24h and 147 of 1,763 over 7d, with 4 CLEAR→CRITICAL against 42 real ones.
The contexts observation was a separate bug. Alarm-processor accepted contexts and forwarded it, but lean search never mapped it, so you got the room's newest 100 events unfiltered. charts was lost the same way: feed-svc had renamed the key, and alarm-processor still sent the old name.
What callers get now
History comes from feed-svc only. There are no current-state rows.
page_size is 1–1000 and defaults to 1000. Pass next_cursor back as cursor until it comes back empty. total is the match count across all pages. Paging no longer skips events that share a timestamp.
contexts and charts filter. Names must match exactly: ["azure_monitor.*"] matches nothing, so list the full context names.
after and before are Unix timestamps in milliseconds.
Every row has event_id, which is unique per row (transition_id can repeat), plus units and value_string on old and new.
old.duration is the number of seconds spent in the status left. The top-level non_clear_duration is the number of seconds since the alert left CLEAR. Both are omitted when unknown. Events written before 1.29.3 have no old.duration.
Lookups by transitions still read stored state, up to 1000 IDs on one page.
Also found and fixed
The room endpoint's database half filtered by space only. Since 1.23.1, anyone who could open a room saw alerts for every node in the space.
Lean search replaced the permitted-action filter with the caller's actions, so any space member could read events their role does not allow.
On nodes reported by several claims, a de-escalation took the surviving claim's previous state (for example CLEAR→CLEAR). It was dropped from history and from notifications. Those clears now appear and notify.
Node-level events were stamped with processing time instead of the agent's transition time, 0–537s off on staging.
The cloud-insights get_alert_transitions tool reported truncated results as complete. It now reports "N of total".
Changes
Change
PR
Release
Scope to the room's nodes; send charts as chart_ids
Activity
car12o commentedon Nov 5, 2026
Fixed and deployed. The endpoint now returns every transition in the window, newest first. It pages them and reports a total, and each row now includes
old.duration.Why raises were missing
A history response merged two sources:
node_instance_alarms, presented as a transition.Most instances are CLEAR at any given moment, so the second source was mostly
→CLEARrows, includingUNKNOWN→CLEARinitialisations. A flapping alert showed up once, as its last clear. That is how 3h returned 1,098 rows with only 5CLEAR→CRITICAL. On staging the endpoint covered 119 of 322 transitions over 24h and 147 of 1,763 over 7d, with 4CLEAR→CRITICALagainst 42 real ones.The
contextsobservation was a separate bug. Alarm-processor acceptedcontextsand forwarded it, but lean search never mapped it, so you got the room's newest 100 events unfiltered.chartswas lost the same way: feed-svc had renamed the key, and alarm-processor still sent the old name.What callers get now
page_sizeis 1–1000 and defaults to 1000. Passnext_cursorback ascursoruntil it comes back empty.totalis the match count across all pages. Paging no longer skips events that share a timestamp.contextsandchartsfilter. Names must match exactly:["azure_monitor.*"]matches nothing, so list the full context names.afterandbeforeare Unix timestamps in milliseconds.event_id, which is unique per row (transition_idcan repeat), plusunitsandvalue_stringonoldandnew.old.durationis the number of seconds spent in the status left. The top-levelnon_clear_durationis the number of seconds since the alert left CLEAR. Both are omitted when unknown. Events written before 1.29.3 have noold.duration.transitionsstill read stored state, up to 1000 IDs on one page.Also found and fixed
actions, so any space member could read events their role does not allow.CLEAR→CLEAR). It was dropped from history and from notifications. Those clears now appear and notify.get_alert_transitionstool reported truncated results as complete. It now reports "N of total".Changes
chartsaschart_idsold.duration,non_clear_durationcontextsfilter and action permissionsNetdata.alert.previous.duration