What an Amazon SES bounce notification tells you

Read Amazon SES bounce types, subtypes, and optional recipient diagnostics, and see how Sendtier stores events and applies suppressions.

An Amazon SES bounce notification reports the bounce type and subtype. Each recipient entry may also include an action, status, and diagnostic code, depending on the delivery status notification available to SES. The bounce type, not the SMTP digits, decides whether you stop sending.

For a transient bounce, the notice means Amazon SES has stopped retrying.

Where the JSON comes from

Amazon SES publishes bounce, complaint, and delivery notices to Amazon SNS as JSON. A classic notice uses notificationType, while event publishing uses eventType. Both shapes include mail, and a bounce also includes bounce. See notification contents and event data.

One notice can list several recipients, and Amazon SES guarantees neither order nor batch size. Delivery and bounce are separate messages, and a bounce can follow a delivery. Accept unknown fields.

mail.destination is the original recipient list, and bouncedRecipients is who bounced. mail.messageId is the ID from send time, and mail.source is the envelope MAIL FROM address.

Event publishing includes hard bounces and soft bounces whose retries have stopped. A delivery-delay event reports a soft bounce while retry is still running. Enable delivery-delay events to receive notifications about soft bounces before SES stops retrying.

An example notification

This JSON is an example, and the addresses, IDs, host, and IP are made up. The field names match the notification contents page.

{  "notificationType": "Bounce",  "mail": {    "timestamp": "2026-10-07T09:14:02.000Z",    "messageId": "01000199madeup-message-id-000000",    "source": "receipts@orders.example",    "destination": ["ada@mailbox.example", "bo@mailbox.example"]  },  "bounce": {    "bounceType": "Permanent",    "bounceSubType": "General",    "bouncedRecipients": [      {        "emailAddress": "ada@mailbox.example",        "action": "failed",        "status": "5.1.1",        "diagnosticCode": "smtp; 550 5.1.1 user unknown"      },      {        "emailAddress": "bo@mailbox.example",        "action": "delayed",        "status": "4.0.0"      }    ],    "timestamp": "2026-10-07T09:14:11.000Z",    "feedbackId": "01000199madeup-feedback-id-000000",    "reportingMTA": "dns; outbound.example.com",    "remoteMtaIp": "203.0.113.10"  }}

bounceType is Permanent for both addresses. bo@mailbox.example has status 4.0.0 and no diagnostic code, and Amazon SES's own sample uses that same shape.

bounceType

Amazon SES sets bounceType to Permanent, Transient, or Undetermined, and calls the first a hard bounce and the second a soft bounce. RFC 5321 and RFC 3463 do not use those labels. They use the reply's first digit and the class of the dotted code.

Permanent. Remove the address. Event publishing says a future send will not succeed, and notification contents says a later send is unlikely. Further general hard bounces can lead Amazon SES to pause your sending.

Transient. SES has stopped retrying this message, but a later send may succeed once the cause is resolved.

Undetermined. Amazon SES could not name a reason. The bounce message lacked detail, though mail to the Return-Path address might say more. Keep the event, which proves neither delivery nor a dead mailbox.

bounceSubType

The table merges both Amazon SES pages, checked on 7 October 2026.

TypeSubtypeWhat Amazon SES says
PermanentGeneralGeneral hard bounce. Remove the address.
PermanentNoEmailPermanent. The two pages disagree on the cause. See below.
PermanentSuppressedAlready suppressed after recent invalid-address bounces.
PermanentOnAccountSuppressionListOn the account suppression list. Not sent. Outside the bounce rate.
PermanentOnTenantSuppressionListOn the tenant suppression list. Not sent. Outside the bounce rate.
PermanentUnsubscribedRecipientListed only in the notification-contents table. List unsubscribe. No delivery, no SES suppression, and no reputation effect.
PermanentEmailValidationSuppressedMissed your email validation threshold. Not sent.
TransientGeneralA later send may work. Notification contents: an out-of-office reply can use this subtype and stays out of the bounce rate.
TransientMailboxFullThe inbox was full. A later send may work once it has space.
TransientMessageTooLargeSend a smaller message.
TransientContentRejectedChange the content, then send again.
TransientAttachmentRejectedChange or remove the attachment content, then send again.
TransientCustomTimeoutExceededListed only in the event-publishing table. Not delivered within the time you set.
UndeterminedUndeterminedAmazon SES could not name a specific reason.

NoEmail is permanent on both pages, and the descriptions disagree. Notification contents says the address could not be read from the bounce message. Event publishing says the address does not exist and should be removed. Store the subtype you received.

Recipient fields

Each object in bouncedRecipients has emailAddress, and that is the address to act on. When a DSN is attached, the object can also include action, status, and diagnosticCode, and any of those three can be missing.

status is the DSN Status code, and 5.1.1 means the mailbox does not exist. RFC 3463 class 5 means an unchanged resend is unlikely to work, and class 4 means a later attempt may succeed. RFC 5321 uses 5yz and 4yz for that same split.

Gmail sends 550 5.1.1 with this text: "The email account that you tried to reach does not exist." The next line says to check for typos and spaces. Yahoo says not to retry a missing account, and to remove the address.

diagnosticCode is the reporting MTA's text, and the Amazon SES sample uses smtp; 550 user unknown. The event data page says this: "This field may be absent in the DSN (and therefore also absent in the JSON)." Preserve missing diagnostics as absent or empty values.

action is the DSN Action, and the SES sample puts failed and delayed inside one Permanent bounce.

reportingMTA appears when a DSN was attached. A classic notice adds remoteMtaIp when Amazon SES reached the remote MTA, and event publishing's bounce object does not list that IP. feedbackId is the bounce ID, and bounce.timestamp is when the ISP sent the notice, not when Amazon SES received it.

Four mistakes

Retrying a permanent bounce

Stop on Permanent. Yahoo says not to retry a 5xx. A corrected spelling is a new submission, and RFC 5321 allows that new attempt. Waiting does not repair 5.1.1.

Treating the digits as the type

The SES type and the SMTP digits can disagree. The SES sample puts status 4.0.0 inside bounceType Permanent, so a check that looks only for a 5 keeps that address.

Permanently suppressing an address solely because its reply starts with 5 is also unreliable. Microsoft's public-folder article uses 554 5.2.2 for a full folder and tells the sender to try later. Gmail uses 452 4.2.2 when the inbox is out of space, and 552 5.2.2 when it is full and inactive. RFC 3463 says mailbox-full should be transient, so a permanent 5.2.2 conflicts with that note.

RFC 2034 says a 4yz reply uses enhanced class 4, and a 5yz reply uses class 5. Gmail also lists 421 5.7.32, a transient reply with a permanent enhanced class. On an SES notice, read bounceType.

Ignoring Undetermined

Undetermined is still a bounce. Discarding it loses evidence of a failed delivery. Suppress it forever and you may block a working mailbox; keep the fields and review the address.

Dropping the diagnostic text

5.1.1 says the mailbox does not exist, and the diagnostic text may provide more context. Gmail mentions a typo or a stray space. Microsoft's 5.1.1 article also names a stale cache after migration, a bad forward, and an MX problem. Some bounces include no diagnostic code, so handle an empty value.

What we store

Sendtier is in public preview. The API runs in AWS eu-central-1 (Frankfurt) and sends through Amazon SES there. AWS is a subprocessor (draft list), and live delivery is limited.

We keep the SES type and subtype, and for each recipient the action, status, and diagnostic code. We also keep the reporting MTA and remote MTA IP when Amazon SES sends them. Status is an enhanced code such as 5.1.1. The diagnostic code is the server reply when included, for example smtp; 550 5.1.1 user unknown.

We use bounceType to decide automatic suppression: permanent bounces suppress every reported address, regardless of subtype. Complaints also trigger suppression; transient and undetermined bounces do not. A Permanent UnsubscribedRecipient is still suppressed, even though Amazon SES adds no suppression for that subtype.

A send to a suppressed address fails with 422 recipient_suppressed. Add, list, and remove your own entries under suppressions. We keep the event for 30 days by default. See retention.

Bounce and delay notifications produce email.bounced and email.delayed webhooks. Signing and retries are in the webhooks guide, and the quickstart shows the send request. A test key (st_test_…) can accept a send while DNS is still pending, and we do not deliver that message.

This excerpt shows stored bounce fields for one example recipient; it is not a complete webhook payload.

{  "bounce_type": "Permanent",  "bounce_subtype": "General",  "reporting_mta": "dns; outbound.example.com",  "remote_mta_ip": "203.0.113.10",  "recipients": [    {      "email": "ada@mailbox.example",      "action": "failed",      "status": "5.1.1",      "diagnostic_code": "smtp; 550 5.1.1 user unknown"    }  ]}

Start free with a test key.