Alarms in ALARM state: the basics
What does it mean when a CloudWatch alarm is "in ALARM"?
A CloudWatch alarm watches a single metric (or a math expression over several) and evaluates it against a threshold over a configurable window. It sits in one of three states at any moment: OK (within bounds), ALARM (currently breaching), or INSUFFICIENT_DATA (no recent data to judge from). An alarm "in ALARM" means the metric is breaching the threshold right now, for the number of evaluation periods configured, not that it breached once last week.
What "bad" looks like is an alarm that has been ALARM for days, weeks, or months. Either the underlying problem was never resolved (a queue is permanently backed up, an EFS mount is permanently failing, a disk is permanently full) or the alarm itself is broken: the threshold is wrong, the metric stopped reporting, the resource was deleted, or someone changed the workload pattern and never updated the alarm.
Check ALM-001 flags this exact pattern: alarms whose StateValue is ALARM at the time of evaluation. It's deliberately a loud signal: a healthy estate has alarms that transition occasionally and then settle back to OK. A long-running ALARM is almost always a symptom of either an unaddressed incident or an alarm that needs decommissioning.
In this lesson you'll learn how to triage an alarm that's currently in ALARM state, how to distinguish a real incident from a stale or misconfigured alarm, and how to fix the underlying condition without falling into the trap of silencing the signal. You'll see real CLI investigation against describe-alarms and describe-alarm-history, the math behind alarm evaluation, and the right way to confirm a resolution stuck.
The "always red" dashboard problem
It's common for a large estate to carry a meaningful fraction of its alarms in a non-OK state at any given time, and for engineers to quietly tune out a channel once it's been red for a couple of weeks. The dangerous part isn't the noise; it's the training effect. When the dashboard is always red, the team learns to glance past it, and when a real fire starts in the same panel nobody sees it for hours. Alarm hygiene isn't about pretty dashboards; it's about preserving the team's ability to react when it actually matters.
Triaging a stuck ALARM in action
Marco is the on-call SRE at a UK retailer. ALM-001 fires a CRITICAL finding: alarm SainsburysWs1EfsUnhealthy on metric ClientConnections has been in ALARM state for 9 days. No PagerDuty incident, no ticket, no Slack mention. The alarm is firing into a channel nobody watches.
He doesn't know yet whether this is a real EFS problem that someone has been ignoring or whether the alarm is broken; those need very different fixes. Step one is to look at the alarm's transition history: did it move from OK to ALARM at a specific moment (smells like an incident), or has it always been ALARM since creation (smells like a misconfiguration)?
He starts with describe-alarms scoped to ALARM state, then drills into the history of the offending one.
First, list every alarm currently in ALARM state, the same query ALM-001 runs internally.
Currently-ALARM alarms across the account. Notice the spread of StateUpdatedTimestamp ages.
Next, pull the transition history for the EFS alarm. The state-update events tell you exactly when it last moved between OK and ALARM, and whether it's been ALARM since day one.
The alarm transitioned cleanly OK → ALARM at 14:22 on 2026-05-06. Now find what changed at that moment in the EFS metric.
Alarm state evaluation under the hooddeep dive
A CloudWatch alarm evaluates its metric over a fixed window: Period seconds at a time, against EvaluationPeriods consecutive data points. The transition from OK to ALARM happens when DatapointsToAlarm of those data points breach the threshold. Defaults are 5-minute periods, 1 evaluation period, 1 datapoint, but production alarms typically widen this (e.g. 3 of 5 periods) to avoid flapping on a single spike.
The ALARM state persists as long as the breach continues or until the metric reports enough non-breaching data points to clear the condition. This is why an alarm doesn't "self-heal" the moment you fix the workload; you need at least DatapointsToAlarm consecutive OK data points to flip back. For a 3-of-5 alarm on a 5-minute period, that's roughly 15 minutes of clean data after the fix lands.
If the underlying resource is deleted, the metric stops reporting and the alarm's behaviour depends on its TreatMissingData configuration. missing (the default) transitions the alarm to INSUFFICIENT_DATA once every data point in the evaluation range is absent. ignore retains the current state, so an alarm that was ALARM when the resource vanished stays ALARM forever. notBreaching flips to OK; breaching flips to ALARM. Setting this thoughtfully is the difference between an alarm that gracefully decommissions itself and one that pollutes the dashboard for months after the resource is gone.
# Inspect an alarm's full evaluation config: period, datapoints, missing-data behaviour.
aws cloudwatch describe-alarms \
--alarm-names SainsburysWs1EfsUnhealthy \
--query 'MetricAlarms[0].{Period:Period,EvalPeriods:EvaluationPeriods,Datapoints:DatapointsToAlarm,Threshold:Threshold,Comparison:ComparisonOperator,Missing:TreatMissingData,Dimensions:Dimensions}'
# Pull the metric chart for the moment the alarm transitioned.
aws cloudwatch get-metric-statistics \
--namespace AWS/EFS \
--metric-name ClientConnections \
--dimensions Name=FileSystemId,Value=fs-0abc12345def67890 \
--start-time 2026-05-06T13:00:00Z \
--end-time 2026-05-06T15:30:00Z \
--period 60 \
--statistics Sum What is the impact of leaving an alarm stuck in ALARM?
The most visible impact is the missed incident. If SainsburysWs1EfsUnhealthy has been ALARM for 9 days, the workload behind it has been degraded for 9 days, or the alarm is broken and nobody noticed for 9 days. Either way, the team's understanding of the system's health has been wrong for over a week. The cost is whatever the EFS-backed workload was doing for those users in that time.
The second-order impact is alarm fatigue. Every stuck alarm trains the on-call rotation to ignore that channel, and over time, to ignore other channels too. A single "always red" alarm doesn't sound expensive until you realise it's the reason your team missed the database failover at 4am. Reliability is partly a function of attention; permanent ALARMs eat attention.
The third impact is composability. CloudWatch composite alarms let you express "page me if X AND Y but not Z", but composite alarms inherit state from their children. One broken child alarm that's permanently ALARM poisons every composite that depends on it. The fix tends to be either decommissioning the child or hard-coding workarounds, both of which add maintenance debt.
And there's a real audit impact: SOC 2 CC7.2 and ISO 27001 A.12.4 expect monitoring controls to be operating effectively. A pile of permanently-ALARM alarms is direct evidence to an auditor that the monitoring control is not being operated; "we have alarms" stops being the answer when the alarms have been red for a quarter and nobody investigated.
How do you resolve an alarm stuck in ALARM?
Resolving a stuck alarm is a four-step loop. The order matters: jumping to the fix without understanding which kind of stuck you're dealing with is how teams end up disabling alarms instead of fixing systems.
1. Read the history before touching anything
Use describe-alarm-history to see when the alarm transitioned and how often. A clean OK→ALARM transition at a specific timestamp is an incident: go look at deploys, traffic, and infrastructure changes around that moment. A history that's been ALARM since the alarm was created points at misconfiguration. A history full of OK→ALARM→OK flapping is a noisy alarm: fix the threshold or the evaluation window, don't fix the workload.
2. Fix the underlying condition, not the alarm
If it's a real incident, the alarm exists to tell you to do something: go do it. Restart the unhealthy mount, scale the queue worker, replace the failing disk. Don't reach for set-alarm-state to flip it to OK as a workaround. Manually-set OK is sticky until the next evaluation, but it papers over the signal that the next time the alarm should fire, the underlying condition is probably still there. Fix it, then wait for the alarm to clear on its own.
3. Distinguish ALARM from INSUFFICIENT_DATA
If the metric isn't reporting at all, an alarm set to missing (the default) should be in INSUFFICIENT_DATA, not ALARM. If it's reading ALARM despite no data, check TreatMissingData on the alarm config; ignore retains whatever state it was last in, so a resource that was ALARM when it vanished stays stuck there. That's a separate failure mode from a real breach and needs a different fix (usually deleting the alarm because the resource was deleted, or setting TreatMissingData=notBreaching for resources that come and go).
4. Group dependent alarms with composite alarms
If one EFS goes unhealthy and triggers five dependent alarms (mount, throughput, IOPS, latency, app errors), that's one incident, not five. A composite alarm with ALARM("efs-unhealthy") OR ALARM("mount-failing") etc. gives you a single page and a clean dashboard tile. Composite alarms reduce noise without losing fidelity; the children still record state, they just don't all page individually.
# Don't do this: manually flipping state to OK doesn't fix the underlying problem.
# aws cloudwatch set-alarm-state \
# --alarm-name SainsburysWs1EfsUnhealthy \
# --state-value OK \
# --state-reason 'Cleared by on-call'
# Do this: confirm the metric is healthy, then let the alarm clear on its own.
aws cloudwatch get-metric-statistics \
--namespace AWS/EFS --metric-name ClientConnections \
--dimensions Name=FileSystemId,Value=fs-0abc12345def67890 \
--start-time $(date -u -d '30 minutes ago' +%FT%TZ) \
--end-time $(date -u +%FT%TZ) \
--period 60 --statistics Sum
# When you genuinely need to suppress dependent alarms during an incident, group them.
aws cloudwatch put-composite-alarm \
--alarm-name efs-fleet-unhealthy \
--alarm-rule 'ALARM("SainsburysWs1EfsUnhealthy") OR ALARM("SainsburysWs1EfsThroughput")' \
--actions-enabled Quick quiz
Question 1 of 5An alarm on ClientConnections has been in ALARM for 9 days. describe-alarm-history shows a single clean OK→ALARM transition 9 days ago and no transitions since. What's the right next move?
You scored
0 / 5
Keep learning
Dig deeper into alarm evaluation, composite alarms, and alarm hygiene.
- CloudWatch Alarms: Evaluating an alarm The official mechanics: periods, datapoints, evaluation windows, and TreatMissingData semantics.
- CloudWatch Composite Alarms Group dependent alarms into one logical signal to cut noise without losing fidelity.
- AWS Well-Architected: Operational Excellence Pillar Where alarm design fits into the broader observability and incident-response practice.
- Google SRE Book: Monitoring distributed systems Canonical guidance on actionable alerts, alert fatigue, and what should and shouldn't page a human.
You've completed Resolve alarms stuck in ALARM state. You can now triage a stuck alarm by reading its history, distinguish a real incident from a misconfigured signal, fix the underlying condition without manually overriding the alarm, and bundle dependent alarms into composite signals to keep the dashboard honest. The next time ALM-001 fires at 2am, you'll have a four-step loop ready to run.
Back to the library