CloudWatch Alarm Not Sending Email or SNS Notifications: Unconfirmed Subscriptions, the Encrypted-Topic KMS Trap, Disabled Actions, and How to Test With set-alarm-state

Logeshwaran
—

If a CloudWatch alarm goes into ALARM but no email or SNS notification arrives, the cause is almost always one of five things: the email subscription was never confirmed; the SNS topic is encrypted with the AWS managed key alias/aws/sns, which CloudWatch cannot use; the alarm's actions are disabled; the topic is attached to the wrong state (OK instead of ALARM); or the alarm is already in ALARM, because alarms notify on state changes, not continuously. The fastest test is aws cloudwatch set-alarm-state --alarm-name my-alarm --state-value ALARM --state-reason test, then aws cloudwatch describe-alarm-history --alarm-name my-alarm --history-item-type Action, which records every notification CloudWatch tried and whether it failed. The encryption trap catches teams that switch on "encrypt everything": CloudWatch can publish to an encrypted topic only if the topic uses a customer managed KMS key whose key policy lets cloudwatch.amazonaws.com use kms:Decrypt and kms:GenerateDataKey*. This guide walks through each cause, with a read-only checker script we tested against six broken setups.

Jake's shop has an alarm on the booking server's CPU. One Tuesday the site crawled for an hour, the alarm was red in the console the whole time, and nobody got an email. "So what was the alarm for?" Jake asked. "For the console," Ethan said. "Somewhere between the alarm and your inbox, a message was dropped, and the alarm history says where."

⚡ Quick Answer

• Test it: set-alarm-state --state-value ALARM, then read describe-alarm-history --history-item-type Action. How to test.

• Email never came: the subscription is "PendingConfirmation"; click the link in the confirmation email. Confirm.

• Encrypted topic: use a customer managed KMS key that allows cloudwatch.amazonaws.com; alias/aws/sns cannot work. The KMS trap.

• Actions disabled: aws cloudwatch enable-alarm-actions --alarm-names my-alarm. Disabled actions.

• Only one email: alarms notify when the state changes, not while it stays in ALARM. One email per change.

Topic policy · Wrong state · Checker script · Custom message · User Notifications · Symptoms · FAQ

New to this? A CloudWatch alarm watches a metric and moves between three states: OK, ALARM and INSUFFICIENT_DATA. For each state you can attach actions, most often an Amazon SNS topic, and SNS delivers the message to the topic's subscriptions: email addresses, phone numbers, Lambda functions, queues or chat tools. Our plain-English SNS guide explains topics and subscriptions. This page assumes the alarm itself changes state; if yours never leaves the gray INSUFFICIENT_DATA state, start with our INSUFFICIENT_DATA guide instead.

🧭 NEW HERE? READ THESE FIRST

New to CloudWatch or SNS? Start with these five pages:

💡 Split the problem in two before you change anything: did the alarm try to send (alarm history), and did SNS deliver it (subscriptions and SNS metrics)? Each half has different causes.

How to test an alarm's notification in two minutes

  1. Force the alarm into ALARM without waiting for a real problem:
    aws cloudwatch set-alarm-state --alarm-name booking-cpu-high \
        --state-value ALARM --state-reason "Testing notifications"
    The alarm switches state and runs its ALARM actions, then returns to its real state at the next evaluation. If it is already in ALARM, set it to OK first and then to ALARM, because actions run on a change.
  2. Read what CloudWatch did with the action:
    aws cloudwatch describe-alarm-history --alarm-name booking-cpu-high \
        --history-item-type Action --max-records 5 \
        --query "AlarmHistoryItems[].[Timestamp,HistorySummary]" --output text
    A successful publish and a failed one both appear here. A failure entry names the topic and the error that stopped it, which points straight at one of the causes below.
  3. Check delivery on the SNS side: in the SNS console, the topic's Subscriptions tab shows whether each one is Confirmed, and CloudWatch's AWS/SNS metrics (NumberOfMessagesPublished, NumberOfNotificationsDelivered, NumberOfNotificationsFailed) show whether SNS received the message and passed it on.

Reading the result:

What you seeWhere the problem isLook at
History shows the action failedBetween CloudWatch and the topicTopic encryption key, topic policy, topic ARN
History shows success, SNS shows a published message, no emailDelivery from SNS to youSubscription status, spam folder, SMS limits
No action in the history at allThe alarm never triedActions enabled, the state the topic is on, whether the state changed

If history shows a successful action and SNS shows a published message, the alarm side is fine and the problem is delivery: an unconfirmed subscription, a spam filter, or an SMS limit. If history shows a failure, the problem is between CloudWatch and the topic: encryption, the topic policy, or a deleted topic.

The six causes at a glance, so you can jump to yours:

CauseHow you spot itFix
Unconfirmed email subscriptionSubscription shows PendingConfirmationRequest confirmation and click the link
Topic encrypted with alias/aws/snsAlarm history shows a failed actionCustomer managed key with a CloudWatch statement
Actions disabledActionsEnabled is falseenable-alarm-actions
Topic on the wrong stateTopic only under OK or INSUFFICIENT_DATAAdd it to AlarmActions
Already in ALARMNo state change in the historyWait for OK, or test with set-alarm-state
Topic policy excludes CloudWatchFailed action in the history; custom topic policyAdd a statement for cloudwatch.amazonaws.com

Cause 1: the email subscription was never confirmed

When you subscribe an email address to a topic, SNS sends a confirmation email with a link, and the subscription stays PendingConfirmation until someone clicks it. SNS delivers nothing to a pending subscription. The confirmation email often lands in spam, is sent to a shared inbox nobody reads, or expires before anyone acts on it.

  • Check: aws sns list-subscriptions-by-topic --topic-arn arn:aws:sns:us-east-1:111122223333:alerts. A subscription whose SubscriptionArn is literally PendingConfirmation is not confirmed.
  • Fix: in the SNS console, choose the subscription and Request confirmation, then click the link in the new email (check spam and quarantine folders). Our pending confirmation guide covers expired links, filters that eat the email, and confirming from the CLI.
  • Console-created topics: when you create an alarm in the console and choose "Create new topic", CloudWatch creates a topic (often named Default_CloudWatch_Alarms_Topic) and subscribes your email, which still needs confirming.

This was Jake's problem: the confirmation had gone to an old address that forwarded to nowhere. Ethan subscribed Jake's current address and a team mailbox, confirmed both, and ran the test again.

Cause 2: the topic is encrypted with a key CloudWatch cannot use

You can encrypt SNS topics at rest with AWS KMS, and many teams turn this on for every topic, maybe yours too. CloudWatch, like other AWS services that publish to SNS (EventBridge, S3 notifications, CodeCommit and more), must be allowed to use the topic's key. Two rules follow:

  • The AWS managed key alias/aws/sns cannot work. Its key policy is controlled by AWS and you cannot add CloudWatch to it.
  • Use a customer managed key, and add a statement to its key policy that lets the CloudWatch service use it:
{
  "Sid": "AllowCloudWatchAlarmsToUseTheKey",
  "Effect": "Allow",
  "Principal": { "Service": "cloudwatch.amazonaws.com" },
  "Action": [ "kms:GenerateDataKey*", "kms:Decrypt" ],
  "Resource": "*"
}

Then point the topic at that key:

aws sns set-topic-attributes --topic-arn arn:aws:sns:us-east-1:111122223333:alerts \
    --attribute-name KmsMasterKeyId --attribute-value arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

The same key policy statement is needed for each service that publishes to the topic (for example events.amazonaws.com for EventBridge rules). The failure is silent unless you look: the alarm changes state normally and the console shows the action configured, but the alarm history records a failed action. If you encrypt topics by policy across an organization, give alarm topics a customer managed key from the start. Our IAM policy JSON guide explains statements and principals, which work the same way in key policies.

Cause 3: the alarm's actions are disabled

Your alarm can have actions configured and still be silent, because actions can be switched off. This happens after maintenance (someone disabled actions to stop pages during a deploy and never turned them back on), and in some infrastructure-as-code templates that set actions off by default. You still see the state change in the console; nothing runs.

# check
aws cloudwatch describe-alarms --alarm-names booking-cpu-high --query "MetricAlarms[].[AlarmName,ActionsEnabled]"
# fix
aws cloudwatch enable-alarm-actions --alarm-names booking-cpu-high

In CloudFormation, the property is ActionsEnabled; in Terraform, actions_enabled. If you disable actions on purpose during maintenance, put the re-enable step in the same runbook or pipeline.

To find every silenced alarm in a Region at once, list the ones with actions off: aws cloudwatch describe-alarms --query "MetricAlarms[?ActionsEnabled==\`false\`].AlarmName". Ethan ran it on Jake's account and found two, both left over from a server move in the spring. "So they were never going to tell us anything," Jake said. "Not since April," Ethan said.

Cause 4: the topic is on the wrong state

Your alarm has a separate action list for each state: AlarmActions (entering ALARM), OKActions (returning to OK) and InsufficientDataActions. If your topic sits only under OK actions, you hear about recovery and never about the problem. In the console, edit the alarm and check the Notification section: each block starts with "Alarm state trigger", and the one that matters is In alarm.

aws cloudwatch describe-alarms --alarm-names booking-cpu-high \
    --query "MetricAlarms[].{alarm:AlarmActions,ok:OKActions,insufficient:InsufficientDataActions}"

Many teams add the same topic to both AlarmActions and OKActions, so the inbox shows when a problem started and when it ended.

Composite alarms follow the same rules: the composite alarm needs its own actions, and you usually remove the actions from the child alarms so you get one notification per incident instead of one per child. If you build alarms from templates, check that the template fills AlarmActions and not only OKActions; a copied block with the wrong property name is easy to miss in review.

Cause 5: the alarm is already in ALARM (one email per change)

Your alarm's actions run when it transitions into a state. An alarm that has been in ALARM since last night sends nothing more, however long it stays there, and a metric that keeps breaching does not produce a stream of emails. If you created an alarm that started in ALARM, or a problem began before you added the topic, no notification is coming until the alarm goes back to OK and then into ALARM again.

If you want repeated reminders while something stays broken, CloudWatch alarms alone will not do it. Options: a scheduled Lambda function that checks for alarms still in ALARM and re-notifies, or an incident tool such as AWS Systems Manager Incident Manager that pages on a schedule until someone responds.

Cause 6: a topic policy that no longer allows CloudWatch

When you create a topic, its default access policy lets resources in your own account publish, which covers alarms in the same account. Trouble starts when someone replaces the policy, for example to lock the topic down to one application role, and leaves CloudWatch out. For alarms in another account, the topic policy must allow them explicitly. A policy statement for CloudWatch that also guards against the confused deputy problem:

{
  "Sid": "AllowCloudWatchAlarms",
  "Effect": "Allow",
  "Principal": { "Service": "cloudwatch.amazonaws.com" },
  "Action": "SNS:Publish",
  "Resource": "arn:aws:sns:us-east-1:111122223333:alerts",
  "Condition": {
    "ArnLike": { "aws:SourceArn": "arn:aws:cloudwatch:us-east-1:111122223333:alarm:*" },
    "StringEquals": { "aws:SourceAccount": "111122223333" }
  }
}

The aws:SourceArn and aws:SourceAccount conditions mean only alarms from your account can publish through the CloudWatch service principal. Replace the account in both conditions with the alarm's account when the alarm lives elsewhere.

Lab: a read-only checker for alarm-to-SNS problems

This script walks every alarm (or the ones you name) and checks the causes above: actions enabled, which states have SNS actions, whether each topic exists, whether its encryption key can work with CloudWatch, the topic policy, confirmed versus pending subscriptions, and recent failed actions in the alarm history. It only reads; it changes nothing.

#!/usr/bin/env python3
"""alarm_sns_doctor.py [--region R] [ALARM_NAME ...]: why a CloudWatch alarm is not reaching its SNS topic. Read-only."""
import json, sys, boto3

def kms_ok(kms, key_id):
    if key_id in ('alias/aws/sns',) or key_id.endswith(':alias/aws/sns'):
        return False, 'AWS managed key alias/aws/sns: its policy cannot allow CloudWatch; use a customer managed key'
    try:
        pol = json.loads(kms.get_key_policy(KeyId=key_id, PolicyName='default')['Policy'])
    except Exception as e:
        return False, f'cannot read key policy ({type(e).__name__}); check it allows cloudwatch.amazonaws.com'
    for st in pol.get('Statement', []):
        p = st.get('Principal', {}); svc = p.get('Service') if isinstance(p, dict) else None
        svcs = svc if isinstance(svc, list) else [svc]
        acts = st.get('Action'); acts = acts if isinstance(acts, list) else [acts]
        if st.get('Effect') == 'Allow' and 'cloudwatch.amazonaws.com' in svcs and \
           any(a in ('kms:Decrypt', 'kms:*') for a in acts) and any(a.startswith('kms:GenerateDataKey') or a == 'kms:*' for a in acts):
            return True, 'key policy allows cloudwatch.amazonaws.com Decrypt + GenerateDataKey*'
    return False, 'key policy has no statement allowing cloudwatch.amazonaws.com kms:Decrypt and kms:GenerateDataKey*'

def main():
    args = sys.argv[1:]; region = None
    if '--region' in args: i = args.index('--region'); region = args[i + 1]; args = args[:i] + args[i + 2:]
    cw = boto3.client('cloudwatch', region_name=region); sns = boto3.client('sns', region_name=region); kms = boto3.client('kms', region_name=region)
    alarms = cw.describe_alarms(AlarmNames=args)['MetricAlarms'] if args else \
             [a for p in cw.get_paginator('describe_alarms').paginate() for a in p['MetricAlarms']]
    for a in alarms:
        print(f"== {a['AlarmName']}  state={a['StateValue']}")
        if not a.get('ActionsEnabled', True): print('  ERROR actions are disabled (enable-alarm-actions)')
        per_state = {'ALARM': a.get('AlarmActions', []), 'OK': a.get('OKActions', []), 'INSUFFICIENT_DATA': a.get('InsufficientDataActions', [])}
        sns_any = False
        for state, acts in per_state.items():
            topics = [x for x in acts if x.startswith('arn:aws:sns:')]
            print(f'  {state:17} -> {len(topics)} SNS action(s)' + ('' if topics or state != 'ALARM' else '   WARN nothing is sent when it enters ALARM'))
            for t in topics:
                sns_any = True
                _, _, _, t_region, t_acct, _ = t.split(':', 5)
                _, _, _, a_region, a_acct, _ = a['AlarmArn'].split(':', 5)
                if (t_region, t_acct) != (a_region, a_acct):
                    print(f'    WARN {t} is in {t_region}/{t_acct}, alarm is in {a_region}/{a_acct}: the topic policy must allow it')
                try: attrs = sns.get_topic_attributes(TopicArn=t)['Attributes']
                except Exception as e: print(f'    ERROR {t}: {type(e).__name__} (deleted, wrong ARN, or no access)'); continue
                key = attrs.get('KmsMasterKeyId')
                if key:
                    ok, why = kms_ok(kms, key); print(f"    {'OK   ' if ok else 'ERROR'} encryption: {why}")
                pol = attrs.get('Policy', '')
                if pol and 'cloudwatch.amazonaws.com' not in pol and 'SourceOwner' not in pol:
                    print('    WARN topic policy neither allows cloudwatch.amazonaws.com nor keeps the default SourceOwner statement')
                subs = [s for p in sns.get_paginator('list_subscriptions_by_topic').paginate(TopicArn=t) for s in p['Subscriptions']]
                pending = [s for s in subs if s['SubscriptionArn'] == 'PendingConfirmation']
                confirmed = [s for s in subs if s['SubscriptionArn'] != 'PendingConfirmation']
                print(f'    subscriptions: {len(confirmed)} confirmed, {len(pending)} pending confirmation' +
                      ('   ERROR nobody will receive anything' if not confirmed else ''))
        if not sns_any: print('  WARN no SNS actions at all')
        try:
            hist = cw.describe_alarm_history(AlarmName=a['AlarmName'], HistoryItemType='Action', MaxRecords=5)['AlarmHistoryItems']
        except Exception as e:
            print(f'  (alarm history not available: {type(e).__name__})'); hist = []
        for h in hist:
            if 'Failed' in h.get('HistorySummary', ''): print(f"  ERROR history {h['Timestamp']:%Y-%m-%d %H:%M}: {h['HistorySummary'][:150]}")

if __name__ == '__main__': main()

Run it as python3 alarm_sns_doctor.py --region us-east-1 booking-cpu-high with read permissions for CloudWatch, SNS and KMS. We tested it against six deliberately broken alarms in moto, a library that mocks AWS locally. The key lines from its output:

== cpu-managed-key
    ERROR encryption: AWS managed key alias/aws/sns: its policy cannot allow CloudWatch; use a customer managed key
== cpu-cmk-missing-statement
    ERROR encryption: key policy has no statement allowing cloudwatch.amazonaws.com kms:Decrypt and kms:GenerateDataKey*
== cpu-good
    OK    encryption: key policy allows cloudwatch.amazonaws.com Decrypt + GenerateDataKey*
== cpu-ok-only
  ALARM             -> 0 SNS action(s)   WARN nothing is sent when it enters ALARM
== cpu-actions-disabled
  ERROR actions are disabled (enable-alarm-actions)

Two parts needed a different test, because the mock is more forgiving than AWS: moto treated our email subscription as confirmed straight away (real SNS keeps it pending until someone clicks the link), and it does not implement the alarm history call. So we checked those branches with botocore's Stubber, feeding the script a pending email subscription and a sample failed-action entry:

== cpu-email-unconfirmed  state=ALARM
    subscriptions: 0 confirmed, 1 pending confirmation   ERROR nobody will receive anything
  ERROR history 2026-10-24 06:15: Failed to execute action arn:aws:sns:us-east-1:111122223333:alerts. Received error: (sample entry)

On a real account, that history line shows the actual error text for your failure.

When the alarm publishes but the email still does not arrive

  • Spam and quarantine: alarm emails come from no-reply@sns.amazonaws.com. Add it to your allow list, and check corporate quarantine, which users often cannot see.
  • A bounced or unsubscribed address: someone may have clicked "unsubscribe" in an earlier alarm email, which removes the subscription. List subscriptions again.
  • SMS limits: new accounts send text messages from the SMS sandbox (verified numbers only) and with a low monthly spending limit; messages stop when the limit is reached.
  • Lambda or HTTPS subscribers: check the function's logs or the endpoint's access log; SNS retries failed HTTP deliveries for a while and then gives up. A dead-letter queue on the subscription keeps failed messages for inspection.

Customizing the alarm message

An SNS email from an alarm is plain text with a fixed layout, and SNS has no template feature. If you need a friendlier subject or body, a chat-friendly format, or extra details such as a runbook link, send the notification through something that can shape it:

  • A Lambda function subscribed to the topic that reads the alarm JSON (alarm name, new state, reason, metric) and sends your own email, chat message or ticket.
  • An EventBridge rule on the "CloudWatch Alarm State Change" event with an input transformer, which can format a message and send it to SNS, a chat channel or an API destination. Our EventBridge rule guide covers event patterns.
  • The alarm description is included in the notification, so a short runbook link there costs nothing.

AWS User Notifications: another way to get alarm emails

AWS User Notifications can deliver CloudWatch alarm state changes by email, to chat, or to the AWS Console Mobile Application, using the events alarms emit to EventBridge. It does not use the alarm's action list, so it works even for alarms nobody attached a topic to, and it can group bursts of notifications into one. By default it covers all alarms in the Regions you pick; an advanced filter narrows it, for example to alarms named ServerCpuTooHigh moving from OK to ALARM. For a few critical alarms, SNS with confirmed subscriptions is still the simplest; for "tell me about any alarm in production", User Notifications saves wiring every alarm by hand.

A checklist for alarms that must reach people

  1. Subscribe at least two addresses (a person and a team mailbox), and confirm both.
  2. Put the topic on both AlarmActions and OKActions.
  3. If the topic is encrypted, use a customer managed key with the CloudWatch statement.
  4. Keep ActionsEnabled on, and re-enable it in the same runbook that disables it.
  5. After any change, run set-alarm-state and check describe-alarm-history and the inbox.
  6. Alarm on SNS's NumberOfNotificationsFailed for the topic, so a broken delivery path tells you about itself.

Put the test from step 5 on a calendar too. Mailboxes change, people leave and keys rotate, and a monthly two-minute test is the only way you find out before a real incident does it for you.

Symptoms and their usual causes

The alarm is red in the console, but nobody got an email

Check the subscription status first (PendingConfirmation), then the alarm history for a failed action, then whether actions are enabled.

The alarm history shows "Failed to execute action" for the SNS topic

CloudWatch could not publish. The usual causes are an encrypted topic whose key does not allow cloudwatch.amazonaws.com, a topic policy that excludes CloudWatch, or a deleted topic.

We get an email when things recover, not when they break

The topic is under OK actions only. Add it to AlarmActions (the In alarm trigger).

We got one email and then nothing, although the problem continued

That is normal: actions run on state changes. Use a re-notification function or an incident tool for reminders.

The test with set-alarm-state worked, but real alarms do not notify

The real alarm is probably never changing state: check its metric, period and missing-data settings, or whether it is already in ALARM.

Text messages stopped arriving

The account may be in the SMS sandbox or have reached its SMS spending limit. Check the SNS text messaging settings.

CloudWatch alarm notifications: frequently asked questions

Why is my CloudWatch alarm not sending email?

Most often the email subscription is still PendingConfirmation, the topic is encrypted with a key CloudWatch cannot use, alarm actions are disabled, the topic is on the wrong state, or the alarm was already in ALARM.

How do I test a CloudWatch alarm notification?

Run aws cloudwatch set-alarm-state --alarm-name NAME --state-value ALARM --state-reason test, then check the inbox and aws cloudwatch describe-alarm-history --history-item-type Action.

How do I set up a CloudWatch alarm email notification?

Create an SNS topic, subscribe your email address and confirm the link, then add the topic to the alarm's In alarm notification (AlarmActions).

What is Default_CloudWatch_Alarms_Topic?

A topic the console creates when you choose to create a new topic while making an alarm. It is an ordinary SNS topic, and its email subscriptions still need confirming.

Can CloudWatch alarms publish to an encrypted SNS topic?

Yes, if the topic uses a customer managed KMS key whose policy lets cloudwatch.amazonaws.com use kms:Decrypt and kms:GenerateDataKey*. The AWS managed key alias/aws/sns cannot be used.

Does a CloudWatch alarm send repeated notifications?

No. Actions run when the alarm changes state. While it stays in ALARM, no further notifications are sent.

How do I enable alarm actions?

Run aws cloudwatch enable-alarm-actions --alarm-names NAME, or set ActionsEnabled to true in your template.

Where can I see whether an alarm action failed?

In the alarm's history: the History tab in the console, or describe-alarm-history with --history-item-type Action.

Can a CloudWatch alarm notify an SNS topic in another account?

Yes, if the topic's access policy allows the alarm's account (or the CloudWatch service principal with SourceAccount and SourceArn conditions for that account).

Can I customize the CloudWatch alarm email?

Not in SNS itself. Use a Lambda subscriber or an EventBridge rule with an input transformer to send your own formatted message, and put a runbook link in the alarm description.

Do alarms send notifications for INSUFFICIENT_DATA?

Only if you add actions for the INSUFFICIENT_DATA state. By default the console sets up notifications for In alarm only.

What is the difference between SNS notifications and AWS User Notifications for alarms?

SNS notifications come from each alarm's own action list. AWS User Notifications listens to alarm state change events for all alarms in chosen Regions and can deliver by email, chat or mobile push.

Why do I get alarm emails for OK as well as ALARM?

The topic is attached to OKActions as well. That is often useful, but remove it from OKActions if you only want problem alerts.

How do I send an alert based on a log message in CloudWatch?

Create a metric filter on the log group, alarm on the resulting metric, and attach an SNS topic to the alarm's In alarm state. Our metric filter guide covers the first step.

How do I know SNS delivered the alarm message?

Check the topic's AWS/SNS metrics in CloudWatch: NumberOfMessagesPublished for arrivals and NumberOfNotificationsDelivered or NumberOfNotificationsFailed for delivery.

Why didn't my alarm notify when I created it in the ALARM state?

There was no transition into ALARM after the action was attached. Set it to OK and back to ALARM with set-alarm-state to test.

For readers preparing for an AWS certification

We have been covering AWS certifications alongside our fixes, so here is a short extra for readers studying for one. If you only came for the fix, you already have it; feel free to skip this part.

Exams that test this topic: CloudOps Engineer – Associate (SOA-C03) • Security – Specialty (SCS-C03) • Developer – Associate (DVA-C03 from December 1, 2026).

Here are the exam-style questions this topic tends to raise, with the reasoning you need to answer them:

1. A CloudWatch alarm enters ALARM, but the on-call engineer never receives the email from the alarm's SNS topic. The subscription shows PendingConfirmation. What is the fix?

Confirm the email subscription (request confirmation again and click the link); SNS does not deliver to unconfirmed subscriptions.

2. A security policy requires all SNS topics to be encrypted. After encryption with the AWS managed key alias/aws/sns, CloudWatch alarm notifications stop. How should this be fixed?

Encrypt the topic with a customer managed KMS key whose key policy allows cloudwatch.amazonaws.com to use kms:GenerateDataKey* and kms:Decrypt.

3. An operations engineer wants to verify that an alarm's notification path works without waiting for a real incident. What should they do?

Run set-alarm-state to put the alarm into ALARM temporarily, then check the inbox and the alarm history for the Action item.

4. After a maintenance window, alarms change state but no notifications are sent, although their SNS actions are configured. What is the likely cause?

Alarm actions were disabled for maintenance and not re-enabled; run enable-alarm-actions (ActionsEnabled true).

5. A team wants to be notified both when a problem starts and when it is resolved. How should the alarm be configured?

Add the SNS topic to both AlarmActions and OKActions.

6. Where can an engineer see whether CloudWatch failed to publish an alarm notification to SNS?

In the alarm history (describe-alarm-history with HistoryItemType Action), which records successful and failed actions.

Exam codes and dates change often. Our AWS certification changes page keeps track of what is current.

πŸ“š ALSO READ

More CloudWatch and alerting guides for the same project:

📌 Bookmark this page. Run the two-minute test after every change to an alarm or its topic.

The next time the booking server ran hot, two phones buzzed within a minute, and a second email arrived when it calmed down. "So the alarm was fine all along," Jake said. "The alarm was fine," Ethan said. "The mailbox it was talking to wasn't listening." If your results differ from what this page describes, please tell us. Guides like this stay right because readers write in.

📌 If you keep one line from this page

Force the alarm with set-alarm-state and read its Action history: a failure there is encryption, policy or a missing topic, and success there with no email is an unconfirmed subscription or a spam filter.

Confirm subscriptions · customer managed KMS key, not alias/aws/sns · ActionsEnabled on · AlarmActions, not only OKActions · one email per state change · October 24, 2026.

Revision note. Written October 24, 2026, with a checker tested against six broken alarm setups. "No news is good news," the saying goes, but not from an alarm: silence is the symptom.

Related