Every time an email fails to deliver, the receiving mail server sends back a status code that explains why. Most senders never read these codes. They see “bounced” in their email platform, sigh, and move on.
That is a mistake. SMTP bounce codes are diagnostic gold. They tell you whether an address is permanently dead, temporarily unreachable, blocked by a spam filter, or sitting behind a catch-all server that will never confirm delivery. Read them correctly and you can clean your list, protect your sender reputation, and stop wasting sends on addresses that will never convert.
This guide breaks down the bounce codes you will actually encounter, what each one means, and the action to take for each.
How SMTP Status Codes Are Structured
Every bounce code follows a predictable format. There are two layers.
The first layer is the basic response code, a three-digit number like 250, 421, or 550. The first digit is the most important:
- 2xx means success. The message was accepted.
- 4xx means a temporary failure. Try again later.
- 5xx means a permanent failure. Do not retry.
The second layer is the enhanced status code, a more granular set of numbers like 5.1.1 or 4.2.2. These follow the pattern class.subject.detail:
- The class (first number) mirrors the basic code: 2 is success, 4 is temporary, 5 is permanent.
- The subject points to the category of problem: 1 is the address, 2 is the mailbox, 4 is the network, 7 is security or policy.
- The detail narrows it down further.
So 550 5.1.1 reads as: permanent failure (550), address problem (5.1), bad destination mailbox address (5.1.1). In plain English, that email address does not exist.
Hard Bounce Codes (5xx): Permanent Failures
These are the codes that should trigger immediate removal from your list. Sending to them again does real damage to your reputation.
550 5.1.1 - User Unknown / Mailbox Does Not Exist
The single most common hard bounce. The mailbox you tried to reach is not a valid account on that server. The person left the company, the address was mistyped, or it never existed at all.
Action: Remove immediately. Repeated sends to nonexistent addresses are the fastest way to get flagged as a spammer.
550 5.1.10 - Recipient Address Rejected (Microsoft)
A Microsoft-specific variant of user unknown. Outlook and Office 365 servers return this when the address does not resolve to a real mailbox.
Action: Remove immediately.
550 5.7.1 - Message Rejected by Policy / Blocked
The address may exist, but the server refused your message. This usually means your sending IP or domain is on a blocklist, or the recipient’s spam policy rejected you outright.
Action: Do not simply remove the contact. Investigate your sender reputation. Check whether your domain is listed on major blocklists and review your authentication setup (SPF, DKIM, DMARC).
554 5.7.1 - Relay Access Denied / Spam Content
A blunt rejection. The receiving server decided your message looked like spam, or refused to relay it. Content, formatting, or reputation triggered a filter.
Action: Audit your email content and reputation before sending to this domain again.
Soft Bounce Codes (4xx): Temporary Failures
These addresses are not necessarily bad. The failure is temporary, and a retry may succeed. Most email service providers retry 4xx bounces automatically for 24 to 72 hours before giving up.
421 4.7.0 - Service Not Available / Try Again Later
The server is temporarily unavailable or is deliberately slowing you down. This is often greylisting, a spam-prevention technique where the server rejects unknown senders on the first attempt and accepts them on the retry.
Action: Let your platform retry. If it keeps failing across multiple campaigns, treat the address as risky.
452 4.2.2 - Mailbox Full / Over Quota
The recipient’s inbox is full. The address is valid, but there is no room for your message.
Action: Retry later. If the mailbox stays full across weeks, the account is likely abandoned and can be removed.
451 4.3.0 - Local Error in Processing
A temporary problem on the receiving server’s side. Nothing to do with your address quality.
Action: Retry. No cleanup needed.
The Tricky One: Catch-All and “Accept-All” Servers
Here is where bounce codes stop being reliable. A catch-all server accepts mail for every address at a domain, whether or not the specific mailbox exists. So you send to [email protected], the server returns 250 OK, and your validation tool marks the address as valid.
Except the mailbox might not exist. The server accepted the message and then silently discarded it, or will bounce it internally later where you never see the code. You get a clean 250 and a message that never reaches a human.
This is why so many email lists look healthy on paper but still underperform. Standard SMTP validation cannot see past a catch-all. Most tools mark these as “unknown” or “risky” and leave them in your list, and you find out they were dead only after your campaign bounces or gets no engagement.
Scrubby was built specifically to solve this. Instead of stopping at the 250 OK, it runs deeper checks to determine whether a catch-all address actually resolves to a real, reachable inbox. That means the addresses other validators leave as “unknown” get a real verdict, so you can send with confidence instead of guessing.
A Quick Reference Table
| Code | Type | Meaning | Action |
|---|---|---|---|
| 550 5.1.1 | Hard | Mailbox does not exist | Remove |
| 550 5.1.10 | Hard | Recipient rejected (Microsoft) | Remove |
| 550 5.7.1 | Hard | Blocked by policy / blocklist | Check reputation |
| 554 5.7.1 | Hard | Rejected as spam / relay denied | Audit content |
| 421 4.7.0 | Soft | Temporarily unavailable / greylisted | Retry |
| 452 4.2.2 | Soft | Mailbox full | Retry, then remove if persistent |
| 451 4.3.0 | Soft | Server processing error | Retry |
| 250 OK | Success | Accepted (may still be catch-all) | Verify further |
Turning Bounce Codes Into a Cleaner List
Reading bounce codes after a campaign is reactive. You have already taken the deliverability hit by the time the codes come back. The better approach is to validate before you send, so the dead addresses never enter the campaign in the first place.
A solid pre-send workflow looks like this:
- Export your list from your CRM or email platform.
- Run it through validation to catch the obvious 5xx addresses, disposable domains, and role-based accounts before they bounce.
- Resolve the catch-alls. This is the step most tools skip. Use a validator like Scrubby that verifies catch-all and accept-all addresses instead of leaving them unknown.
- Segment by risk and send to your clean, verified contacts first.
Do this consistently and your bounce reports get boring, which is exactly what you want. Fewer hard bounces means better inbox placement, a stronger sender reputation, and more of your emails reaching people who can actually reply.
Bounce codes are the mail server telling you the truth about your list. Validate before you send, decode the codes you do get, and act on them, and you turn a pile of cryptic error messages into a genuinely deliverable audience.

Amit S.
Marketing Lead