Uploaded image for project: 'Observability UI'
  1. Observability UI
  2. OU-1020

[Incidents] Incorrect Silence Matching for Alerts with Same Name but Different Labels

XMLWordPrintable

    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      Alerts with the same alertname but different labels (namespace, severity, component) incorrectly show the same silence state in the Incidents UI. When one alert is silenced, all alerts with the same name appear silenced, regardless of whether the silence matchers match their specific labels.

      Description

      Problem Statement

      The Incidents page incorrectly applies silence state to alerts by matching only on alertname, ignoring other critical label fields such as namespace, severity, and component. This causes alerts that should not be silenced to display as silenced in the UI when another alert with the same name is silenced.

      Root Cause

      In processAlerts.ts, the code matches alerts to Prometheus rules using only the alert name:

      // Line 167 in processAlerts()const matchingRule = alertingRules.find((rule) => rule.name === alert.metric.alertname);// Line 186
      silenced: matchingRule ? matchingRule.state === 'silenced' : false,

      And similarly in groupAlertsForTable():

      {{// Lines 200-203
      if (alertingRulesData): {   rule = alertingRulesData.find((rule) => alertname === rule.name); }

      const silenced = rule?.state === 'silenced';}}

      This naive lookup returns the first rule with a matching name, regardless of whether that rule's alert instances match the specific alert's labels. When multiple alerts share the same name but differ in other labels, they all get assigned the same rule and thus the same silence state.

      I tested it with following silences rules:

       

      And alerts:

      And both of the alerts are shown as silences, only though the rule should match only the storage one.

      Silence matching in other components

      web/src/components/alerting/AlertUtils.tsx:

      // Lines 555-566
      const isAlertSilenced = (alert: PrometheusAlert, silence: Silence): boolean => {
        return (
          isAlertFiring(alert) &&
          silence.matchers.every((matcher) => {
            const alertValue = alert.labels[matcher.name] ?? '';
            const isMatch = matcher.isRegex
              ? new RegExp(`^${matcher.value}$`).test(alertValue)
              : alertValue === matcher.value;
            return matcher.isEqual === false && alertValue ? !isMatch : isMatch;
          })
        );
      };

      As oposed to the code in Incidents/processAlerts.ts, it matches all the labels that the silence carries.

        1. image-2025-09-30-13-43-45-518.png
          196 kB
          David Rajnoha
        2. image-2025-09-30-13-44-47-692.png
          414 kB
          David Rajnoha
        3. image-2025-09-30-13-46-21-502.png
          128 kB
          David Rajnoha

              afalossi@redhat.com Alberto Falossi
              drajnoha@redhat.com David Rajnoha
              None
              None
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: