Amazon SNS errors and delivery failures
Look up an SNS API exception (AuthorizationError, NotFound, InvalidParameter, Throttled, KMS*, EndpointDisabled, batch and limit errors), and find out why a published message never reached a subscriber — retry tables per endpoint type, permanent failures that aren't retried, discard without a subscription DLQ, queue and key policies, filter policies, unconfirmed subscriptions — including the topic policy CloudWatch alarms and EventBridge need to publish.
markdownreferencev4CH67-VC09stage: operatetrust: officialservice: snsinterface: anyAuthorizationErrorExceptionNotFoundException SNSInvalidParameterException SNSInvalidParameterValueExceptionThrottledExceptionKMSAccessDeniedExceptionKMSDisabledExceptionKMSNotFoundExceptionKMSThrottlingExceptionEndpointDisabledExceptionFilterPolicyLimitExceededExceptionSubscriptionLimitExceededExceptionTopicLimitExceededExceptionTooManyEntriesInBatchRequestExceptionInvalidSecurityExceptionSNS message not deliveredSNS retry policy100015 attempts 23 days50 attempts 6 hoursSNS discards messagesubscription pending confirmationSNS topic policy cloudwatch.amazonaws.comalarm SNS not publishingEventBridge SNS topic policy
A successful Publish only means SNS accepted the message. Delivery to each subscriber happens afterwards, with its own retries, and failures there never reach the publisher. Check the subscriber side first.
Message published, subscriber got nothing
| Cause | Fix | Check |
|---|---|---|
Queue policy doesn't allow sns.amazonaws.com sqs:SendMessage from this topic | Add the statement with aws:SourceArn = topic (patterns/sns-to-sqs-fanout.md) | aws sqs get-queue-attributes --queue-url <u> --attribute-names Policy |
Encrypted queue on aws/sqs, or a key policy without sns.amazonaws.com | Customer managed key with kms:Decrypt + kms:GenerateDataKey* for SNS, or SSE-SQS | aws sqs get-queue-attributes --attribute-names KmsMasterKeyId, then aws kms get-key-policy --key-id <k> --policy-name default |
| Filter policy excluded it, or was changed less than 15 minutes ago | reference/sns/filter-policies.md | aws sns get-subscription-attributes --subscription-arn <s> → FilterPolicy, FilterPolicyScope |
| Raw delivery to SQS with more than 10 attributes | Discarded as a client-side error. Reduce the attributes or disable raw delivery | Count the message's attributes; get-subscription-attributes → RawMessageDelivery |
| Subscription pending confirmation (email, cross-account SQS) | Confirm it. Email: the link in the "AWS Notifications" message | aws sns list-subscriptions-by-topic --topic-arn <t>: PendingConfirmation as the subscription ARN |
| Permanent error (not 5XX or 429), e.g. permissions | Not retried, then discarded unless the subscription has a DLQ | The subscription DLQ, if any, holds the message; the subscriber's own logs |
| Retries exhausted | Discarded unless the subscription has a DLQ (RedrivePolicy) | get-subscription-attributes → RedrivePolicy present? |
| Lambda subscriber | The function's resource-based policy must allow sns.amazonaws.com to invoke it (reference/lambda/permissions.md) | aws lambda get-policy --function-name <fn>: sns.amazonaws.com with the topic as SourceArn |
Retry schedules
| Endpoint | Schedule | Total |
|---|---|---|
| SQS, Lambda (AWS managed) | 3 immediate; 2 at 1 s; 10 backoff 1–20 s; 100,000 at 20 s | 100,015 attempts over 23 days |
| SMTP, SMS, mobile push (customer managed) | 0 immediate; 2 at 10 s; 10 backoff 10–600 s; 38 at 600 s | 50 attempts over 6 hours |
| HTTP/S | Same four phases; custom delivery policies allowed | Policy-dependent |
| Firehose | Throttling errors use the customer-managed schedule | — |
Only 5XX and 429 responses are retried. Messages SNS holds back because of a subscription's maxReceivesPerSecond are requeued without using attempts.
Other services publishing to your topic
They need a topic policy statement for their service principal, plus key access if the topic is encrypted.
CloudWatch alarms:
{
"Effect": "Allow",
"Principal": { "Service": "cloudwatch.amazonaws.com" },
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:<region>:<topic-account>:<topic>",
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:cloudwatch:<region>:<alarm-account>:alarm:*" },
"StringEquals": { "aws:SourceAccount": "<alarm-account>" }
}
}
If an alarm ARN has non-ASCII characters, condition on aws:SourceAccount only.
EventBridge: sns:Publish for events.amazonaws.com. If the topic is encrypted, the customer managed key also needs kms:Decrypt and kms:GenerateDataKey for events.amazonaws.com. Rules deleted soon after creation can leave this permission on the topic, so remove it with aws sns set-topic-attributes.
API exceptions
| Exception | Meaning → fix | Check |
|---|---|---|
AuthorizationErrorException | Access denied to the topic or action. Check the caller's IAM policy and the topic policy (guides/iam/fix-access-denied.md) | aws sns get-topic-attributes --topic-arn <t> → Policy; the caller's IAM policy |
NotFoundException | The topic, subscription or endpoint doesn't exist. Check the ARN's Region and account | aws sns list-topics --region <r> with the same credentials |
InvalidParameterException, InvalidParameterValueException, ValidationException | A parameter breaks a constraint, for example an invalid filter policy JSON or a FIFO-only parameter on a standard topic (example is the hub's reading) | The message names the parameter; validate filter policies as JSON |
ThrottledException | The request rate exceeds your account's limit for the action. Back off; use PublishBatch | Calls per second in your code; CloudTrail errorCode |
KMSAccessDeniedException, KMSDisabledException, KMSInvalidStateException, KMSNotFoundException, KMSOptInRequired, KMSThrottlingException | The topic's key can't be used by the publisher: no access, disabled, pending deletion, missing, or throttled (reference/kms/key-policies-and-errors.md) | aws sns list-topics --region <r> with the same credentials |
EndpointDisabledException, PlatformApplicationDisabledException | Mobile push endpoint or application disabled | aws sns get-endpoint-attributes --endpoint-arn <e> → Enabled |
FilterPolicyLimitExceededException | Too many filter policies in the account (an adjustable quota). Request an increase | Service Quotas for SNS filter policies; count existing ones |
SubscriptionLimitExceededException, TopicLimitExceededException | Account subscription or topic quota reached | Service Quotas for SNS |
TooManyEntriesInBatchRequestException, BatchRequestTooLongException, BatchEntryIdsNotDistinctException, EmptyBatchRequestException, InvalidBatchEntryIdException | PublishBatch: more than 10 entries, total too large, duplicate IDs, none, or malformed IDs | Count the PublishBatch entries and their IDs |
InvalidSecurityException | Not HTTPS, or not signed with SigV4 | The client's endpoint scheme and signing |
OptedOutException | SMS: the number opted out | aws sns check-if-phone-number-is-opted-out --phone-number <n> |
InternalErrorException | Service-side. Retry with backoff | Retry; if persistent, keep the request ID |
The SNS message size limit wasn't on the collected pages.
When none of these fits
Turn on delivery-status logging for the protocol (UNVERIFIED setup steps; not collected), or attach a subscription DLQ and read what lands there. Check the topic's NumberOfNotificationsFailed metric (UNVERIFIED metric name). Confirm the subscription's PendingConfirmation status and its FilterPolicy with aws sns get-subscription-attributes.