# Hard vs Soft Bounces: SMTP Codes and Suppression Lists

> The difference between hard and soft bounces, how to read SMTP and enhanced status codes, and how to build suppression rules that protect your reputation.

Source: https://pidgely.com/blog/hard-vs-soft-bounces/ · Published: 2026-10-12 · Pidgely

A hard bounce is a permanent delivery failure, such as a mailbox that does not exist, and the address should be suppressed so you never send to it again. A soft bounce is a temporary failure, such as a full mailbox or a receiver throttling you, and the message should be retried with backoff. You tell them apart by the SMTP reply: `5xx` codes and `5.x.x` enhanced status codes (RFC 3463) are permanent, `4xx` and `4.x.x` are transient, but the class alone is not enough to decide whether to suppress an address.

## Where bounces come from

A bounce can reach you in two ways:

1. **Synchronous rejection**: the receiving server refuses the message during the SMTP transaction. Your MTA sees the reply directly.
2. **Asynchronous bounce**: the server accepts the message (`250 OK`) and later fails to deliver it, then sends a Delivery Status Notification (DSN, RFC 3464) back to the envelope sender (the `Return-Path`).

Both must feed the same suppression logic. Asynchronous bounces are the reason you need a return-path address you actually process, which is what VERP makes easy.

## Reading SMTP reply codes

An SMTP reply (RFC 5321) has a three-digit basic code. Many servers add an enhanced status code (RFC 3463, registry in RFC 5248) in the form `class.subject.detail`:

```text
550 5.1.1 <jane@example.com>: Recipient address rejected: User unknown
452 4.2.2 The email account that you tried to reach is over quota
421 4.7.0 Try again later, closing connection
554 5.7.1 Message rejected due to content restrictions
```

- **Class** (`2`, `4`, `5`): success, persistent transient failure, permanent failure.
- **Subject**: `1` addressing, `2` mailbox, `3` mail system, `4` network and routing, `5` mail delivery protocol, `6` message content, `7` security or policy.
- **Detail**: the specific condition.

### Common codes and what to do

| Code | Meaning | Type | Action |
| --- | --- | --- | --- |
| 5.1.1 | Bad destination mailbox (user unknown) | Hard | Suppress immediately |
| 5.1.2 | Bad destination system (domain does not exist or has no MX) | Hard | Suppress, check for typos |
| 5.1.10 | Recipient address has null MX (RFC 7505) | Hard | Suppress |
| 5.2.1 | Mailbox disabled | Hard | Suppress |
| 4.2.2 / 5.2.2 | Mailbox full | Soft (often sent as 5.2.2) | Retry, suppress if persistent |
| 4.4.x | Network or routing problems, connection timed out | Soft | Retry with backoff |
| 4.7.x | Temporary policy, rate limiting, greylisting | Soft | Slow down, retry |
| 5.7.1 | Delivery not authorized, policy or spam block | Policy | Do not suppress the address; investigate |
| 5.7.26 | Authentication failure (Gmail, DMARC/SPF/DKIM) | Policy | Fix authentication |

## The third category: policy bounces

The simple hard/soft split misses the case that matters most for reputation. A `550 5.7.1` saying your message was blocked as spam is permanent for *that message*, but it says nothing about whether the address is valid. If you suppress every address that returns a policy rejection, a single bad day at one provider can wipe out a large share of your Gmail or Outlook audience.

Classify bounces into three buckets:

- **Address failures** (hard): the mailbox or domain does not exist. Suppress permanently.
- **Transient failures** (soft): retry according to a schedule.
- **Policy or reputation failures**: do not suppress; alert a human, pause the stream if the rate is high, and look at authentication, content and complaint data.

Servers are not always consistent. Some return `550` for a full mailbox, others return `5.0.0` with only free text. Robust classifiers check the enhanced code first, then known text patterns per receiving domain, and default to the safest action.

## Retry strategy for soft bounces

RFC 5321 recommends retry intervals of at least 30 minutes and giving up after at least 4 to 5 days. A sensible queue behavior:

- Exponential backoff with jitter: for example 5 min, 15 min, 30 min, 1 h, 2 h, then every 4 h.
- A maximum queue lifetime (often between 24 hours and a few days); transactional messages such as one-time codes lose their value much sooner and may deserve a shorter lifetime.
- Per-destination concurrency limits, so a deferral from one provider slows only that provider.

When the queue lifetime expires, the message becomes a final failure, but the address still did not prove invalid.

## Building a suppression list

A suppression list is the set of addresses your system will refuse to send to, checked before every message is queued. It should contain:

- **Hard bounces** (address failures).
- **Spam complaints** from feedback loops.
- **Unsubscribes**, scoped to the stream or list the person left.
- **Repeated soft bounces**: for example, an address that soft-bounced on several separate sends over more than a week.
- **Manual entries**: role addresses you were asked to stop emailing, legal requests.

Store the reason, source, timestamp and the raw diagnostic code for each entry:

```json
{
  "address": "jane@example.com",
  "reason": "hard_bounce",
  "status": "5.1.1",
  "diagnostic": "smtp; 550 5.1.1 User unknown",
  "stream": "*",
  "created_at": "2026-10-12T14:03:22Z"
}
```

Scope matters. A hard bounce applies to every stream. An unsubscribe from a newsletter should not stop password resets. A complaint usually applies to all non-transactional streams.

Normalize addresses before lookup (lowercase the domain; be careful with the local part, which RFC 5321 treats as case-sensitive even though almost no providers do), and allow removal with an audit trail when a user fixes their mailbox.

## Why bounce rate matters to receivers

Mailbox providers watch how often you hit nonexistent addresses. A sender who regularly mails invalid users is either buying lists or not maintaining them, and both correlate strongly with spam. Old addresses can also be recycled into spam traps. High hard-bounce rates therefore damage reputation even when the rest of your mail is wanted.

## Common mistakes

- **Retrying hard bounces.** Sending again to a `5.1.1` address is pure reputation cost.
- **Suppressing on `5.7.x`** as if the address were dead.
- **Ignoring asynchronous DSNs** because the SMTP transaction returned `250`.
- **Treating auto-replies as bounces** (or the reverse). Out-of-office messages are not DSNs.
- **One global suppression list without reasons**, making it impossible to tell an unsubscribe from a bounce.
- **Validating only at send time** instead of also at signup, with double opt-in for marketing lists.

## Checklist

- [ ] Synchronous and asynchronous bounces processed by the same classifier
- [ ] Enhanced status codes parsed, with text fallbacks
- [ ] Address, transient and policy bounces handled differently
- [ ] Exponential backoff with a defined queue lifetime
- [ ] Suppression checked before queueing, with reason and scope
- [ ] Alerts on policy bounce spikes per receiving domain

Pidgely classifies synchronous replies and DSNs into these categories, adds hard bounces and complaints to the suppression list automatically, and emits a webhook event for each one so your application stays in sync.

## Frequently asked questions

### What is the difference between a hard and a soft bounce?

A hard bounce is a permanent failure, signaled by a 5xx SMTP reply or a 5.x.x enhanced status code, such as a nonexistent mailbox. A soft bounce is a temporary failure (4xx or 4.x.x), such as a full mailbox or throttling, and the message can be retried.

### Should I suppress an address after one hard bounce?

For mailbox-level permanent errors such as 5.1.1 (user unknown), yes, immediately. Policy rejections such as 5.7.1 usually reflect your reputation or content, not the address, and should not trigger permanent suppression on their own.

### How many soft bounces before suppressing an address?

There is no standard. A common approach is to suppress after repeated soft bounces across several separate sends over a period of days, since a mailbox that has been full for weeks is effectively abandoned.

### What is a good bounce rate?

As low as possible. Hard bounces mainly come from stale or unverified lists. A rising hard bounce rate is one of the clearest signals receivers use to identify poor list hygiene.

