Skip to content

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.