A newsletter goes out to four thousand subscribers. Twelve minutes later, eighty-odd messages come back titled "Undeliverable: March update," and most get scrolled past. Buried in each is a line reading 550 5.1.1 The email account that you tried to reach does not exist. That is not boilerplate. It is a diagnosis written by the receiving server in a format meant for software, and it says what went wrong and whether retrying is worth anything.
Most people read the friendly sentence at the top of a bounce and stop. That sentence is written by your own provider and is usually vague. The code underneath came from the server that actually refused the message.
The first digit tells you whether to give up
4xx is temporary. The server is saying "not right now." Yours keeps the message queued and retries on a back-off schedule, typically for hours or days, before issuing a final failure notice. A 4xx arriving as a "delayed" warning needs nothing from you.
5xx is permanent. The server is saying "no, and no next time either." Nothing is retried, and resending by hand is not merely pointless — for some codes it makes deliverability worse. The cheapest place to handle permanent failures is before they happen, which is why running an imported list through an email address verifier beats finding the same problem one rejection at a time.
Beside the three-digit reply sits an enhanced status code shaped like X.Y.Z: 5.1.1, 4.7.1, 5.2.2. The first number repeats the permanent/temporary split, the second names the subject area, the third the detail. That is the part worth learning, because 550 alone is nearly meaningless: 550 5.1.1 and 550 5.7.1 are different failures with different fixes.
Where the real code hides
A bounce is formally a Delivery Status Notification, with a defined structure. Scroll past the human paragraph to the header-style lines. Three matter:
- Final-Recipient — the address that actually failed, which can differ from the one you typed if forwarding was involved.
- Status — the enhanced code, for example 5.1.1.
- Diagnostic-Code — the raw response the remote server sent, usually starting smtp;.
Diagnostic-Code is the most useful, because providers often append a support URL or a reason — "classified as bulk," "IP not permitted to relay" — that no numeric code expresses. In webmail, open the original message source to see it.
The codes you will actually meet
- 550 5.1.1 — mailbox does not exist. The domain accepted the connection, then said this user is unknown. Mistyped, long departed, or never real.
- 552 — size or quota limit. Covers both "mailbox is full" and "message too big." The diagnostic text says which; if it is your attachment, the fix is yours.
- 4.2.2 — mailbox full, temporarily. The same condition, treated as retryable in case space is cleared.
- 550 5.7.1 — blocked on policy or reputation. The receiver knows the address exists and refuses anyway: your IP is listed, authentication does not align, or content matched a rule.
- 421 and 4.7.x — busy, throttled, or greylisted. Greylisting rejects an unfamiliar sender's first attempt and accepts the retry, because real servers retry and bulk software often does not.
- 550 with no detail. The catch-all. Some servers refuse to explain themselves, so as not to help spammers tune attacks. Treat it as permanent and look for patterns.
What to do for each class
Any 4xx: nothing. Resist resending. Your server is already retrying more patiently than you would by hand, and a manual burst from the same IP during a throttling window is exactly the behaviour throttling exists to stop.
5.1.1: fix the list, not the message. This one gets handled backwards. The address was never deliverable, so nothing about your subject line, send time or template changes the outcome. It is a data problem, solved before sending rather than after. Remove it, correct obvious typos — gmial, hotnail, .con — and treat any source producing a cluster of them as suspect.
5.7.1: stop and investigate. The only class where continuing to send worsens things, because each rejection reinforces the reputation judgement behind it. Check that SPF, DKIM and DMARC pass and align for the sending domain, and look up your IP against any blocklist named in the diagnostic text. Then look at the mail itself: the fixes that stop your messages landing in the spam folder tend to clear 5.7.1 too.
552: shrink or wait. Link to the file instead of attaching it; if the mailbox is full, try later and stop if it never clears.
Two rules worth internalising
Never manually retry a 5xx: the decision is made, and each repeat marks you as a sender who ignores answers. And never send again to an address that hard-bounced with 5.1.1 — not next campaign, not "just to check." One permanent rejection is all the information you need, and that is the whole reason hard bounces and soft bounces are counted separately. Suppress it, and before importing a list you did not build yourself, check the addresses before the first send.
Frequently asked questions
Is a 550 always the recipient's fault?
No, and assuming so is how senders miss real problems. A 550 5.1.1 is about their address; a 550 5.7.1 is about you — your IP, authentication, or content. Reading only the first three digits hides that distinction.
How long will my server retry a temporary failure?
It depends on configuration, but a common policy is retrying with widening gaps for a few days, with a warning partway through. That warning is informational, not an action item. Only the final notice, carrying a 5xx code, means the message will never arrive.
What about a soft bounce that keeps repeating?
An address that soft-bounces on every send is effectively dead, even if no server said so outright. A permanently full mailbox produces the same net result as a hard bounce. Set a threshold of a few consecutive failures and suppress the address once it is crossed.