A bounce message looks like noise until you know how to read it, at which point it's one of the most precise diagnostic signals in email. Every bounce carries a numeric SMTP reply code and, usually, an enhanced status code that together tell you exactly what went wrong and whether it's worth trying again.
Anatomy of an SMTP reply
The reply code is three digits. The first digit tells you the category: 2xx is success, 4xx is a temporary failure, 5xx is a permanent failure. Alongside it, most modern servers include an enhanced status code in the form class.subject.detail (for example 5.1.1), which narrows the reason down considerably further than the three-digit code alone.
A raw bounce, annotated
550 5.1.1 The email account that you tried to reach does not exist.
│ │ │ │
│ │ │ └─ detail: specific address problem
│ │ └─── subject: address
│ └───── class: permanent failure
└────────── reply code: rejected outrightSoft bounces vs hard bounces
A 4xx code is a soft bounce: the receiving server is telling you to try again later. It might mean a full mailbox, a temporary rate limit, or a greylisting delay used deliberately to filter automated senders. Most sending systems retry a soft bounce automatically for a period before giving up. A 5xx code is a hard bounce: a permanent failure that will not resolve on retry. The address doesn't exist, the domain doesn't exist, or the message was rejected outright on content or policy grounds. Hard bounces should be suppressed immediately; continuing to send to one damages sender reputation with no possible upside.
Common codes and what they actually mean
Code421
- Class
- Soft
- Typical meaning
- Service temporarily unavailable
- Typical cause
- Receiving server overloaded or rate-limiting your IP
Code450
- Class
- Soft
- Typical meaning
- Mailbox temporarily unavailable
- Typical cause
- Greylisting, or a full mailbox
Code451
- Class
- Soft
- Typical meaning
- Local error / temporary failure
- Typical cause
- Receiving server had a transient processing error
Code452
- Class
- Soft
- Typical meaning
- Insufficient system storage
- Typical cause
- Recipient mailbox is full
Code550
- Class
- Hard
- Typical meaning
- Mailbox unavailable / does not exist
- Typical cause
- Invalid address, or the mailbox was deleted
Code551
- Class
- Hard
- Typical meaning
- User not local
- Typical cause
- Address doesn't belong to the receiving server
Code552
- Class
- Hard
- Typical meaning
- Message size exceeds limit
- Typical cause
- Attachment or message too large for the recipient's policy
Code553
- Class
- Hard
- Typical meaning
- Mailbox name not allowed
- Typical cause
- Malformed address syntax
Code554
- Class
- Hard
- Typical meaning
- Transaction failed / rejected
- Typical cause
- Often content, reputation, or policy-based rejection
| Code | Class | Typical meaning | Typical cause |
|---|---|---|---|
| 421 | Soft | Service temporarily unavailable | Receiving server overloaded or rate-limiting your IP |
| 450 | Soft | Mailbox temporarily unavailable | Greylisting, or a full mailbox |
| 451 | Soft | Local error / temporary failure | Receiving server had a transient processing error |
| 452 | Soft | Insufficient system storage | Recipient mailbox is full |
| 550 | Hard | Mailbox unavailable / does not exist | Invalid address, or the mailbox was deleted |
| 551 | Hard | User not local | Address doesn't belong to the receiving server |
| 552 | Hard | Message size exceeds limit | Attachment or message too large for the recipient's policy |
| 553 | Hard | Mailbox name not allowed | Malformed address syntax |
| 554 | Hard | Transaction failed / rejected | Often content, reputation, or policy-based rejection |
Enhanced status codes: the second number tells the real story
- x.1.x: address status: the mailbox or domain itself is the problem (x.1.1 mailbox doesn't exist, x.1.2 bad domain).
- x.2.x: mailbox status: the mailbox exists but has a problem (x.2.1 disabled, x.2.2 full).
- x.4.x: network/routing status: a problem delivering the message across the network path.
- x.7.x: policy status: the message was blocked on purpose, often for reputation, authentication failure, or content filtering.
Common bounce strings translated
- "Mailbox unavailable" or "user unknown": the address doesn't exist; suppress it permanently.
- "Message rejected due to content" or "message contains prohibited content": a policy filter, not an address problem; review the message body and links.
- "IP temporarily blocked" or "too many connections": a reputation or rate signal on the sending server, not the recipient.
- "Mailbox full": a genuine soft bounce; retry later, but repeated occurrences over weeks suggest an abandoned address.
- "Spam detected" or "message identified as spam": a content or reputation rejection at the policy layer, worth treating as a deliverability signal, not just a single failed send.
What to do with each type
Hard bounces go straight to your suppression list. No exceptions, no manual retry. Soft bounces should retry automatically with backoff, but if the same address soft-bounces across three or more separate days, treat it as a hard bounce and suppress it; a mailbox that's been full for a week isn't coming back. Policy-based rejections (x.7.x, "content" or "spam" strings) deserve a different response entirely: they're telling you something about the message or the sending domain, not the recipient, so investigate the sending pattern before resending anything similar.
Track bounce type, not just bounce rate
A rising hard-bounce rate points at list quality. A rising soft-bounce rate concentrated in 4xx policy codes points at your own domain's reputation. They call for opposite fixes, so don't collapse them into one number.
