---
cuppy_hub: azure
cuppy_path: reference/monitor/alerts.md
cuppy_section: docs
cuppy_doc: 9AN7-KFYD
cuppy_doc_uuid: ff286cc0-46cf-4b99-aa09-a422a623e6da
cuppy_permalink: https://cuppy.io/azure/d/9AN7-KFYD
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/monitor/alerts
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 081a7fa0773f6612e8cf59638e31c7244a4ca6cc0a7c215100ce074a1453a68a
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Azure Monitor alerts

## Which rule

| Rule | Signal | Notes |
|---|---|---|
| **Metric alert** | Platform or custom metrics | Lowest 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 alert** | A KQL query on a workspace or Application Insights | For conditions only logs show; more latent than metrics; needs query permission (below); stateful or stateless |
| **Activity log alert** | Activity log events, Service Health, Resource Health | Always 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

```bicep
// 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.

```bicep
// 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

| Message | Cause → 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 Lighthouse | Register 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 reached | Delete 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)

| HTTP | Meaning → fix |
|---|---|
| 400 | The 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 / 403 | The endpoint's credential is missing, invalid or lacks permission (ITSM: refresh the token) |
| 404 | The webhook, Logic App workflow or function was deleted or renamed: update the action |
| 408 | Endpoint timeout: check it's up and reachable |
| 409 | Conflict: read the response headers |
| 429 | The endpoint is overloaded: let it scale, retry later |
| 500 | Endpoint failure, or Azure can't reach it (private link, firewall rules) |


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
