@aws-sdk/client-sns
>=3.0.0 <4.0.0postconditions12functions6last verified2026-06-24coverage score86%Postconditions: what we check
- send · aws-sns-service-errorerrorWhenAny AWS service error or network failure: topic does not exist (NotFound), insufficient permissions (AuthorizationErrorException), request throttling (ThrottlingException), invalid parameter (InvalidParameterException), endpoint disabled (EndpointDisabledException), KMS key errors (KMSDisabledException, KMSNotFoundException), service unavailable, or any network-level failure (DNS, timeout, connection refused)Throws
SNSServiceException subclass with error.name set to the specific error code (e.g., "NotFound", "AuthorizationErrorException", "InvalidParameterException", "ThrottlingException", "EndpointDisabledException"). For network errors, throws a generic Error or SdkClientError with a connection/timeout message.Required handlingCaller MUST wrap client.send() in try-catch. All SNS operations can fail due to network issues, permission problems, topic deletion, or AWS service outages. Unhandled rejections cause silent message loss (for PublishCommand) or crash notification pipelines. Minimum handling: try { await snsClient.send(new PublishCommand({ TopicArn, Message })); } catch (error) { if (error instanceof SNSServiceException) { console.error(`SNS error [${error.name}]: ${error.message}`); } else { console.error('Network error:', error); } throw error; } For PublishBatchCommand, also check for partial failures in result.Failed array (HTTP 200 returned even when some messages fail).costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - PublishBatchCommand · sns-publish-batch-failed-not-checkederrorWhenPublishBatchCommand returns HTTP 200 but response.Failed is non-empty — some messages were NOT delivered to topic subscribers due to endpoint disabled, KMS errors, authorization errors, or per-message parameter violations. Caller does not check response.Failed after the call.Required handlingCaller MUST inspect response.Failed after every PublishBatch call and handle or alert on any failed entries. Retry SenderFault=false entries (infrastructure failures); do not retry SenderFault=true entries (caller-side errors). Pattern: const response = await snsClient.send(new PublishBatchCommand({ TopicArn, PublishBatchRequestEntries })); if (response.Failed && response.Failed.length > 0) { const retryable = response.Failed.filter(f => !f.SenderFault); const permanent = response.Failed.filter(f => f.SenderFault); if (permanent.length > 0) { console.error('Permanent batch publish failures:', permanent.map(f => `${f.Id}: ${f.Code}`)); } if (retryable.length > 0) { // retry with exponential backoff } }costhighin prodsilent failureusers seelost datavisibilitysilent
- PublishBatchCommand · sns-publish-batch-request-level-errorerrorWhenPublishBatchCommand throws a request-level exception before processing any messages: TooManyEntriesInBatchRequestException (>10 messages), EmptyBatchRequestException, BatchEntryIdsNotDistinctException (duplicate Id fields), InvalidBatchEntryIdException (Id doesn't match [A-Za-z0-9_-]{1,80}), or BatchRequestTooLongException (total payload >256KB).Required handlingValidate batch size (max 10 entries), unique Ids, and total payload size before calling PublishBatchCommand. Wrap in try-catch to handle SNSServiceException.costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[5]
- SubscribeCommand · sns-subscribe-subscription-limit-exceedederrorWhenSubscribeCommand throws SubscriptionLimitExceededException when the AWS account has reached the maximum allowed number of SNS subscriptions. Default limit is account-level and requires AWS Support to increase.Required handlingWrap SubscribeCommand in try-catch and handle SubscriptionLimitExceededException separately from other errors. When caught, alert operations team and submit AWS Support limit increase request. Do NOT silently swallow the error. Pattern: try { const result = await snsClient.send(new SubscribeCommand({ TopicArn, Protocol, Endpoint })); } catch (error) { if (error instanceof SNSServiceException) { if (error.name === 'SubscriptionLimitExceeded') { // Alert ops team — needs AWS limit increase throw new CapacityError('SNS subscription limit reached', error); } throw error; } throw error; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[7]
- SubscribeCommand · sns-subscribe-filter-policy-limit-exceededwarningWhenSubscribeCommand throws FilterPolicyLimitExceededException when a subscription filter policy is provided and the AWS account has exceeded the maximum number of filter policies across all subscriptions. Filter policies enable per-subscription message routing but are counted at the account level.Required handlingCatch FilterPolicyLimitExceededException and alert the operations team. Consider redesigning to use fewer filter policies (e.g., per-topic message attributes instead of per-subscription filtering).costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
- SubscribeCommand · sns-subscribe-pending-confirmation-not-handledwarningWhenSubscribeCommand succeeds but returns "pending confirmation" instead of a real subscription ARN. Caller treats the subscription as active and proceeds to publish messages assuming delivery, but the endpoint (HTTP/S, email) has not yet confirmed the subscription.Required handlingAfter SubscribeCommand, check if result.SubscriptionArn === 'pending confirmation'. If so, inform users to check their email/endpoint for a confirmation request. Design subscription confirmation flows for HTTP/S endpoints. Pattern: const result = await snsClient.send(new SubscribeCommand({ TopicArn, Protocol: 'https', Endpoint: url })); if (result.SubscriptionArn === 'pending confirmation') { // Endpoint must call ConfirmSubscription — subscription not yet active await notifyUser('Please confirm your SNS subscription endpoint'); }costmediumin prodsilent failureusers seelost datavisibilitysilent
- CreateTopicCommand · sns-create-topic-limit-exceedederrorWhenCreateTopicCommand throws TopicLimitExceededException when the AWS account has reached the maximum number of SNS topics (100,000 standard topics or 1,000 FIFO topics per account).Required handlingCatch TopicLimitExceededException and alert the operations team. Audit topic usage to identify unused topics that can be deleted. Request an AWS Support limit increase if needed. Note: CreateTopicCommand is idempotent — calling it with the same topic name does NOT hit the limit again. Only new unique topic names consume the quota.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
- CreateTopicCommand · sns-create-topic-concurrent-access-exceptionwarningWhenCreateTopicCommand throws ConcurrentAccessException when multiple callers attempt to tag the same topic simultaneously during creation. This is a race condition specific to CreateTopic with Tags when concurrent requests arrive.Required handlingCatch ConcurrentAccessException and retry with exponential backoff (it is transient). Do not propagate ConcurrentAccessException to end users.costlowin proddegraded serviceusers seedegraded performancevisibilityvisibleSources[10]
- PublishCommand · sns-publish-endpoint-disabled-not-handlederrorWhenPublishCommand throws EndpointDisabledException (HTTP 400) when the mobile push endpoint (APNs / FCM device token) has been disabled by the push notification service — typically because the token was revoked, the app was uninstalled, or the provider (Apple/Google) flagged the endpoint as invalid. The endpoint must be deleted and re-registered with a fresh token, OR re-enabled via SetEndpointAttributes before retry.Required handlingCatch EndpointDisabledException specifically and route to the device-deregistration flow. Do NOT propagate to user-facing error UI (the user didn't do anything wrong) and do NOT blindly retry. Pattern: try { await snsClient.send(new PublishCommand({ TargetArn: endpointArn, Message })); } catch (error) { if (error instanceof SNSServiceException) { if (error.name === 'EndpointDisabled') { await markEndpointDisabled(endpointArn); return; } if (error.name === 'PlatformApplicationDisabled') { await alertOps('Platform application disabled — check APNs/FCM credentials'); return; } } throw error; }costmediumin prodimmediate exceptionusers seelost datavisibilityvisible
- PublishCommand · sns-publish-kms-error-not-handlederrorWhenPublishCommand throws one of the KMS error family — KMSAccessDeniedException, KMSDisabledException, KMSInvalidStateException, KMSNotFoundException, KMSOptInRequired, or KMSThrottlingException — when the destination topic is encrypted at rest with a KMS customer master key and the key is unavailable to the publishing principal. Distinct from generic AuthorizationError because the failure is on the KMS key, NOT the SNS topic.Required handlingCatch KMS* error names separately from AuthorizationErrorException. Surface the KMS error code to operators so they investigate the KMS key, not the SNS topic. For KMSThrottlingException specifically, retry with exponential backoff (it is transient). Pattern: try { await snsClient.send(new PublishCommand({ TopicArn, Message })); } catch (error) { if (error instanceof SNSServiceException) { if (error.name.startsWith('KMS')) { if (error.name === 'KMSThrottling') { return retryWithBackoff(() => snsClient.send(...)); } await alertOps(`SNS topic encrypted with disabled/inaccessible KMS key: ${error.name}`); throw new InfrastructureError('SNS topic KMS key unavailable', error); } } throw error; }costhighin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
- ConfirmSubscriptionCommand · sns-confirm-subscription-replay-limit-exceedederrorWhenConfirmSubscriptionCommand throws ReplayLimitExceededException when the same confirmation token has been replayed more times than the AWS-imposed limit allows. Indicates either a misbehaving client retry loop or an attempted token-replay attack. The token becomes permanently unusable; a fresh SubscribeCommand call is required to issue a new one.Required handlingCatch ReplayLimitExceededException specifically and trigger a re-subscription flow rather than retrying ConfirmSubscription. Log the event for security review (may indicate token-replay probing) and notify the endpoint owner that re-subscription is required. Pattern: try { await snsClient.send(new ConfirmSubscriptionCommand({ TopicArn, Token })); } catch (error) { if (error instanceof SNSServiceException) { if (error.name === 'ReplayLimitExceeded') { await logSecurityEvent('SNS confirmation token replay limit hit', { TopicArn }); await triggerResubscriptionFlow(TopicArn); return; } if (error.name === 'InvalidParameter') { await notifyUser('Confirmation token expired or invalid — please re-subscribe'); return; } } throw error; }costmediumin prodimmediate exceptionusers seelost datavisibilityvisibleSources[16]
- ConfirmSubscriptionCommand · sns-confirm-subscription-token-invalid-not-handledwarningWhenConfirmSubscriptionCommand throws InvalidParameterException when the token is malformed, expired (older than 2 days), or does not match the TopicArn. The subscription remains in pending state — no exception during SubscribeCommand flagged the problem because confirmation is async.Required handlingWhen InvalidParameterException is thrown by ConfirmSubscriptionCommand specifically, surface a clear "your subscription confirmation expired, please re-subscribe" message to the end user. Do not retry with the same token. Pattern: try { await snsClient.send(new ConfirmSubscriptionCommand({ TopicArn, Token })); } catch (error) { if (error instanceof SNSServiceException && error.name === 'InvalidParameter') { return { ok: false, reason: 'token_expired_or_invalid' }; } throw error; }costlowin prodsilent failureusers seelost datavisibilitysilent
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
- [1]docs.aws.amazon.com/AWSJavaScriptSDK/v3/latestSns
- [2]docs.aws.amazon.com/sns/latest/apiAPI Publish
- [3]docs.aws.amazon.com/sns/latest/dgSns Dead Letter Queues
- [4]aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-jsService Error Handling Modular Aws Sdk Js
- [5]docs.aws.amazon.com/sns/latest/apiAPI PublishBatch
- [6]docs.aws.amazon.com/sns/latest/apiAPI BatchResultErrorEntry
- [7]docs.aws.amazon.com/sns/latest/apiAPI Subscribe
- [8]docs.aws.amazon.com/sns/latest/dgSns Subscription Filter Policies
- [9]docs.aws.amazon.com/sns/latest/dgSendMessageToHttp
- [10]docs.aws.amazon.com/sns/latest/apiAPI CreateTopic
- [11]docs.aws.amazon.com/general/latest/grSns
- [12]docs.aws.amazon.com/sns/latest/dgSns Mobile Application As Subscriber
- [13]docs.aws.amazon.com/sns/latest/apiAPI SetEndpointAttributes
- [14]docs.aws.amazon.com/sns/latest/dgSns Server Side Encryption
- [15]docs.aws.amazon.com/kms/latest/developerguideServices Sns
- [16]docs.aws.amazon.com/sns/latest/apiAPI ConfirmSubscription
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources — @aws-sdk/client-sns
Primary Documentation
AWS SNS JavaScript SDK v3 https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/ Official SDK reference. Lists all commands (PublishCommand, CreateTopicCommand, etc.) and documents that client.send() returns a Promise that rejects on service errors.
SNS Publish API Reference https://docs.aws.amazon.com/sns/latest/api/API_Publish.html Documents all error codes thrown by Publish: AuthorizationErrorException, EndpointDisabledException, InvalidParameterException, KMSAccessDeniedException, KMSDisabledException, KMSInvalidStateException, KMSNotFoundException, KMSOptInRequired, NotFound, PlatformApplicationDisabled, ThrottledException.
SNS Error Handling — AWS Developer Blog https://aws.amazon.com/blogs/developer/service-error-handling-modular-aws-sdk-js/ Explains how SNSServiceException and its subclasses are thrown. error.name contains the AWS error code.
SNS Dead Letter Queues https://docs.aws.amazon.com/sns/latest/dg/sns-dead-letter-queues.html Covers delivery failure scenarios. SNS throws when message delivery fails during send.
SNS Publish Batch API https://docs.aws.amazon.com/sns/latest/api/API_PublishBatch.html Documents partial failure pattern — HTTP 200 with Failed array. Client.send() still throws for auth/network errors; partial failures require inspecting result.Failed.
Error Evidence
The following specific errors are documented as thrown by SNS operations:
NotFound— Topic ARN does not existAuthorizationErrorException— Caller lacks permission to publish to topicInvalidParameterException— Invalid message, subject, or attributeThrottledException— Rate limit exceededEndpointDisabledException— Mobile push endpoint is disabledKMSDisabledException— KMS key for server-side encryption is disabledKMSNotFoundException— KMS key not foundPlatformApplicationDisabled— Mobile platform application disabled
Real-World Usage Evidence
test-repos/nestjs-rest-cqrs-example— SNSClient with publish() calling send() without try-catchtest-repos/wing— SNSClient.send() in publish() method (proper handling with try-catch)- Corpus DB: 6 repos with @aws-sdk/client-sns as runtime dependency (faastjs, skiff-apps, etc.)