Hard bounce vs soft bounce: SMTP codes and what to suppress
· 4 min read · Email validation
A hard bounce is a permanent delivery failure: the receiving server answered with a 5xx code, such as 550 5.1.1 "mailbox does not exist", and retrying won't help. A soft bounce is a temporary failure: a 4xx code for a full mailbox, a rate limit or greylisting, where a later retry may succeed. Suppress hard bounces immediately. Retry soft bounces, and suppress only addresses that keep soft bouncing.
The useful skill is reading the code, because a few 5xx failures are about you, not the address.
The first digit: 4 or 5
RFC 5321 section 4.2.1 defines both classes:
- 4yz, transient negative completion. The command wasn't accepted, but "the error condition is temporary, and the action may be requested again." The sending server should try again.
- 5yz, permanent negative completion. The client "SHOULD NOT repeat the exact request (in the same sequence)."
The basic reply codes you'll see in bounce logs:
| Code | RFC 5321 text | Usually means |
|---|---|---|
| 450 | mailbox unavailable (e.g., mailbox busy or temporarily blocked for policy reasons) | Soft. Greylisting, temporary block. |
| 451 | local error in processing | Soft. Their problem, retry. |
| 452 | insufficient system storage | Soft. Often a full mailbox. |
| 550 | mailbox unavailable (e.g., mailbox not found, no access, or command rejected for policy reasons) | Hard, but check the enhanced code |
| 551 | user not local | Hard |
| 552 | exceeded storage allocation | Size or quota problem. Check the enhanced code. |
| 553 | mailbox name not allowed (e.g., mailbox syntax incorrect) | Hard |
Notice that 550 covers both "no such mailbox" and "rejected for policy reasons". That's why you need the second layer.
Enhanced status codes tell you why
RFC 3463 adds a three-part code, class.subject.detail, which many servers include after the basic code. The class repeats the outcome (4 transient, 5 permanent). The subject and detail say what went wrong:
| Enhanced code | RFC 3463 meaning | Treat as |
|---|---|---|
5.1.1 |
Bad destination mailbox address: "The mailbox specified in the address does not exist." | Hard. Suppress. |
5.1.2 |
Bad destination system address: the domain doesn't exist or can't accept mail | Hard. Suppress. |
x.2.1 |
Mailbox disabled: exists but not accepting messages | Hard if 5, soft if 4 |
4.2.2 |
Mailbox full | Soft |
4.4.1 |
No answer from host | Soft |
5.7.1 |
Delivery not authorized, message refused | About you. Don't suppress the address. |
Google publishes the exact lines Gmail returns in its SMTP error reference. For example, 550 5.1.1 reads "The email account that you tried to reach does not exist", 452 4.2.2 reads "The recipient's inbox is out of storage space", and 5.7.26 is a block because the sender is unauthenticated.
The 5xx bounces that aren't the recipient's fault
A 5.7.x code means policy: your authentication failed, your IP or domain is on a blocklist, or the receiver decided your content looks unsolicited. The address is probably fine. If you suppress it, you lose a real contact and still have the underlying problem. Fix SPF, DKIM and DMARC, check blocklists, and look at what you sent.
Treat bounce classification as a parser problem: key on the enhanced code first, fall back to the basic code, and log the raw text so a human can review anything unclear.
What to suppress
| Bounce | Action |
|---|---|
5.1.1, 5.1.2, 5.1.3, 551, 553 |
Suppress permanently, in every tool that sends |
5.2.1 mailbox disabled |
Suppress |
5.7.x policy |
Don't suppress. Investigate your sending. |
4.2.2 mailbox full |
Retry on later sends. Suppress after repeated failures over weeks. |
4.7.x, 450 greylisting or rate limit |
Retry. The sending server usually does this for you. |
| Repeated soft bounces | Suppress after a threshold you pick and stick to |
Email platforms each set their own threshold for repeated soft bounces. Mailchimp's bounce help page says it allows 7 soft bounces for an address with no subscriber activity and up to 15 for contacts with previous activity before treating the address as a hard bounce. If you run your own sending, pick a number and apply it consistently.
Catching hard bounces before you send
Every hard bounce on a send counts against your sender reputation, so the cheapest hard bounce is the one you never send. An SMTP verifier asks the same question a real delivery would, up to the RCPT TO step, and stops there. pingutil's /v1/verify maps the answers to the same categories as above: a 5.1.1-style rejection becomes invalid / mailbox_not_found, a disabled mailbox mailbox_disabled, a full one risky / mailbox_full, and greylisting or blocks unknown instead of a guess. Rejections aimed at the sender are reported as blocked, never as a missing mailbox. The response includes the raw smtp reply (code, enhanced, message) so you can see what the server said. Details are in the verify endpoint docs, and you can try addresses on the email verification page.
Verification won't catch everything. A server can accept an address during the SMTP conversation and bounce the message later, which is exactly the gap described in why SMTP verification is unreliable. Keep your bounce handling running even on verified lists, and see what a good bounce rate looks like for the thresholds to watch.
Questions people ask
- Should I remove soft-bounced email addresses?
- Not after one soft bounce. Retry them on later sends, and suppress an address only when it keeps soft bouncing over several campaigns. Mailchimp, for example, converts an address to a hard bounce after 7 soft bounces if it has no subscriber activity, or 15 if it does.
- Is a mailbox full error a hard or soft bounce?
- Soft. RFC 3463 says the X.2.2 mailbox full code should be used as a persistent transient failure, and Gmail returns it as 452 4.2.2. Repeated full-mailbox bounces over weeks usually mean the inbox is abandoned, so suppress it eventually.