Technical · 9 min read

AWS SES bounce and complaint handling with SNS — the right way

JR
Jules Rivera
May 4, 2026 · 9 min read

AWS SES gives you production access and then watches your bounce and complaint rates like a hawk. If either metric crosses the threshold, your sending gets paused. The fix is wiring up Amazon SNS so you process these events in real time.

The two numbers that matter

  • Bounce rate: AWS warns at 5%, pauses at ~10%. Industry best practice is under 2%.
  • Complaint rate: AWS warns at 0.08%, pauses at ~0.1%. Industry best practice is under 0.05%.

These thresholds are rolling, not monthly. A sudden spike — even in a single campaign — can trigger a review.

What are bounces?

A hard bounce means the address is permanently undeliverable — the mailbox doesn't exist, the domain doesn't exist, or the server explicitly rejected delivery. You should never send to a hard-bounced address again.

A soft bounce means temporary failure — the mailbox is full, the server is down. SES retries automatically. You don't need to suppress on a single soft bounce, but chronic soft bouncers (5+ soft bounces) should be suppressed.

What are complaints?

A complaint happens when a recipient clicks the spam button in Gmail, Outlook, or Yahoo. Most ISPs send a Feedback Loop (FBL) notification back to the sender. AWS SES receives these and can forward them to you via SNS.

Gmail does not provide individual FBL reports — they only report aggregate data in Gmail Postmaster Tools. Outlook and Yahoo do provide FBL reports.

Setting up SNS notifications

Step 1: In the AWS SES console, go to Configuration → Configuration Sets → Create a configuration set.

Step 2: Add an SNS event destination to the configuration set. Select the event types: Bounce, Complaint, and optionally Delivery.

Step 3: Create (or use an existing) SNS topic. Subscribe an HTTP/HTTPS endpoint to the topic — this is where SES Mailbox receives the events.

# Example SNS message payload for a hard bounce
{
  "notificationType": "Bounce",
  "bounce": {
    "bounceType": "Permanent",
    "bounceSubType": "General",
    "bouncedRecipients": [
      { "emailAddress": "user@nonexistent.com", "diagnosticCode": "550 5.1.1 The email account that you tried to reach does not exist." }
    ],
    "timestamp": "2026-05-04T09:12:33.000Z",
    "feedbackId": "0102..."
  },
  "mail": {
    "source": "noreply@yourdomain.com",
    "destination": ["user@nonexistent.com"]
  }
}

What SES Mailbox does automatically

SES Mailbox handles all of this for you once you connect your AWS credentials:

  • Receives bounce and complaint notifications via SNS in real time
  • Automatically suppresses hard-bounced addresses from all future sends
  • Automatically suppresses complaint addresses
  • Surfaces bounce and complaint rates per campaign in your analytics dashboard
  • Alerts you when your account-level rates approach AWS thresholds

Manual suppression — when you need it

If you migrated from another ESP, you should import your historical bounce and complaint list as a suppression list in SES Mailbox before sending your first campaign. This prevents re-contacting known-bad addresses that would immediately spike your rates.

Pro tip: Set up a dedicated Configuration Set for each sending purpose (marketing, transactional). This lets you see bounce and complaint rates broken out by email type — critical for diagnosing which campaigns are damaging your reputation.

What to do if you're already over the threshold

  1. Stop sending immediately — do not dig the hole deeper
  2. Identify the campaign or segment that caused the spike
  3. Suppress the affected addresses (hard bounces + all complainers)
  4. Reply to AWS Trust & Safety with your root cause analysis and remediation plan
  5. Restart with a much smaller, highly engaged segment

Ready to start sending?

Free plan forever. No credit card required.

Start free →