Azure Monitor alerts — rule types, action groups, limits, log search alert identity, and why alerts don't fire or misfire

Choosing and building Azure Monitor alerts — metric, log search and activity log rules, stateful vs stateless, action groups and their notification rate limits, alert processing rules, a metric alert and a log search alert with its own identity in Bicep, and the fixes for rules that don't fire, fire wrongly, fail to save, or whose actions return HTTP errors.

markdownreferencev19AN7-KFYDstage: operatetrust: officialservice: monitorinterface: iacinterface: cliAzure Monitor alertsmetric alert rulelog search alert ruleactivity log alertservice health alertalert processing ruleaction groupgroupShortName 12 characterscommon alert schemastateful alertstateless alertautoMitigatemetric alert resolves after three checksactivity log alerts 100 per subscriptionlog alert 1-minute frequencyemail 100 per hour per addressSMS one every five minuteswebhook 1500 per minuteMicrosoft.Insights/metricAlertsMicrosoft.Insights/scheduledQueryRulesMicrosoft.Insights/actionGroupslog alert system-assigned identity no permissionsLog Analytics Reader for alert ruleThe query couldn't be validated since you need permission for the logsAuthorizationRequiredErrorRegister resource provider Microsoft.Insights in tenantOne-minute frequency isn't supported for this queryFailed to resolve scalar expression namedcolumnifexistslog alert didn't firelog alert latency 4 minutesmetric alert didn't firealert fired when it shouldn'taction group HTTP 400 401 403 404 408 429 500Secure Webhook no auth contextalert rule quota reached

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Azure Monitor alerts

Which rule

RuleSignalNotes
Metric alertPlatform or custom metricsLowest latency; static or dynamic thresholds; one rule can cover many resources of one type in a region; stateful, resolves when the condition isn't met for three consecutive checks
Log search alertA KQL query on a workspace or Application InsightsFor conditions only logs show; more latent than metrics; needs query permission (below); stateful or stateless
Activity log alertActivity log events, Service Health, Resource HealthAlways stateless; 100 rules per subscription, fixed: for more, send the activity log to a workspace and use log search alerts

Action groups say who or what is told (email, SMS, voice, push, webhook, Secure Webhook, Logic Apps, Functions, Event Hubs, ITSM, runbooks); groupShortName is at most 12 characters. Turn on the common alert schema so every receiver gets one payload shape. Alert processing rules add action groups or suppress notifications at scale (for example during maintenance) without editing rules. Metric, log search and processing-rule counts per subscription are quotas: read the current values on the service limits page and use multi-resource rules or splitting by dimensions before asking for more.

Notification rate limits (fixed): no more than 100 emails an hour per address per region, one SMS and one voice call every five minutes per number, and 1,500 webhook calls a minute per subscription. Rate-limited receivers get a notice and are paused.

Bicep: an action group and a metric alert

// An action group and a metric alert: App Service 5xx responses above 10 in 5 minutes
param appServiceId string
param onCallEmail string

resource onCall 'Microsoft.Insights/actionGroups@2023-01-01' = {
  name: 'ag-oncall'
  location: 'global'
  properties: {
    groupShortName: 'oncall' // at most 12 characters
    enabled: true
    emailReceivers: [
      {
        name: 'oncall-email'
        emailAddress: onCallEmail
        useCommonAlertSchema: true
      }
    ]
  }
}

resource http5xx 'Microsoft.Insights/metricAlerts@2026-01-01' = {
  name: 'alert-app-http5xx'
  location: 'global'
  properties: {
    severity: 2
    enabled: true
    scopes: [appServiceId]
    evaluationFrequency: 'PT1M'
    windowSize: 'PT5M'
    criteria: {
      'odata.type': 'Microsoft.Azure.Monitor.SingleResourceMultipleMetricCriteria'
      allOf: [
        {
          criterionType: 'StaticThresholdCriterion'
          name: 'http5xx'
          metricName: 'Http5xx'
          metricNamespace: 'Microsoft.Web/sites'
          operator: 'GreaterThan'
          threshold: 10
          timeAggregation: 'Total'
        }
      ]
    }
    autoMitigate: true
    actions: [
      {
        actionGroupId: onCall.id
      }
    ]
  }
}

Bicep: a log search alert with its own identity

A system-assigned identity on a log search alert is created without permissions: grant it read on what it queries, or the rule goes unhealthy.

// A log search alert with its own identity, allowed to read the workspace it queries
param location string = resourceGroup().location
param workspaceName string
param actionGroupId string

resource ws 'Microsoft.OperationalInsights/workspaces@2026-03-01' existing = {
  name: workspaceName
}

resource failedLogins 'Microsoft.Insights/scheduledQueryRules@2026-03-01' = {
  name: 'alert-failed-logins'
  location: location
  identity: {
    type: 'SystemAssigned' // created without permissions: see the role assignment below
  }
  properties: {
    severity: 2
    enabled: true
    scopes: [ws.id]
    evaluationFrequency: 'PT5M'
    windowSize: 'PT15M'
    criteria: {
      allOf: [
        {
          query: 'AuditEvents_CL | where Action == "login" and Outcome == "failure"'
          timeAggregation: 'Count'
          operator: 'GreaterThan'
          threshold: 20
          failingPeriods: {
            numberOfEvaluationPeriods: 1
            minFailingPeriodsToAlert: 1
          }
        }
      ]
    }
    autoMitigate: true
    actions: {
      actionGroups: [actionGroupId]
    }
  }
}

var logAnalyticsReader = '73c42c96-874c-492b-b04d-ab87d138a893'

resource ruleCanQuery 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  scope: ws
  name: guid(ws.id, failedLogins.id, logAnalyticsReader)
  properties: {
    roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', logAnalyticsReader)
    principalId: failedLogins.identity.principalId
    principalType: 'ServicePrincipal'
  }
}

The table comes from reference/monitor/diagnostic-settings-and-data-collection.md.

Errors saving a log search alert rule

MessageCause → fix
"The query couldn't be validated since you need permission for the logs" (or HTTP 403, or AuthorizationRequiredError saying Register resource provider Microsoft.Insights in tenant '<tenantId>')The creator can create rules but can't run the query: needs Microsoft.OperationalInsights/workspaces/query/read (workspace context) or Microsoft.Insights/logs/<table>/read (resource context)
AuthorizationRequiredError through Azure LighthouseRegister the Microsoft.Insights providers in the managing tenant
"One-minute frequency isn't supported for this query"The query uses operations the 1-minute optimisation can't handle: use 5 minutes or simplify
"Failed to resolve scalar expression named <>"A column that isn't in the table or wasn't kept by an earlier project: add it, or use columnifexists()
Quota reachedDelete unused rules, split by dimensions, then ask support

Rules that don't fire, or fire wrongly

  • Log search alert silent: check the rule's Resource health; log latency (over about 4 minutes of delay, prefer a metric alert); Mute actions or automatically resolve set; the target moved, renamed or deleted (re-create the rule); the identity lacks permissions; the query started failing (a table with no data for 30 days, a custom table not created yet, a deleted resource in a cross-resource query).
  • Log search alert misfires: very late data (over about 30 minutes) can trigger it; alerting on missing data (heartbeats) works poorly with logs.
  • Metric alert silent: the alert is already active (stateful); wrong dimensions, aggregation or granularity; the first evaluation period missing; the alert fired but its actions were muted or rate-limited.

Action group errors (test the action group to see them)

HTTPMeaning → fix
400The endpoint rejected the payload, the alert type lacks the common schema, or a Secure Webhook has Entra auth on without an auth context: check the action's settings
401 / 403The endpoint's credential is missing, invalid or lacks permission (ITSM: refresh the token)
404The webhook, Logic App workflow or function was deleted or renamed: update the action
408Endpoint timeout: check it's up and reachable
409Conflict: read the response headers
429The endpoint is overloaded: let it scale, retry later
500Endpoint failure, or Azure can't reach it (private link, firewall rules)

Read this document as markdown — the same bytes an agent receives.