Home / Hard Bounce vs Soft Bounce: SMTP Codes, Retry Rules, and How to Prevent Them
Hard Bounce vs Soft Bounce: SMTP Codes, Retry Rules, and How to Prevent Them
Published 2026-10-18
A hard bounce is a permanent delivery failure. The address or domain does not exist, or the receiving server refuses your mail for good. A soft bounce is a temporary failure, like a full mailbox or a busy server, and the message may go through on a later try. That is the short answer to hard bounce vs soft bounce. What matters more is what you do next: suppress hard bounces right away, retry soft bounces with a limit, and stop bad addresses before they get into your list.
Key takeaways
- SMTP reply codes starting with 4 are temporary (soft bounce). Codes starting with 5 are permanent (hard bounce). RFC 5321 defines both classes.
- Read the enhanced status code too, like 5.1.1 or 4.2.2. RFC 3463 uses these codes to say why a message failed as well as whether it failed.
- Not every hard bounce means the address is bad. Policy rejections (5.7.x) often mean your authentication or reputation needs fixing, so fix those before you remove contacts.
- Amazon SES counts only hard bounces in its bounce rate. It reviews accounts at 5% and may pause sending at 10%.
- Typos, dead domains and domains with no MX record can be caught at signup with a DNS-based check. No DNS-only check can prove that a specific mailbox exists.
What a hard bounce and a soft bounce are (and what they are not)
A bounce is a delivery failure reported back to the sender. It can happen in two ways. Sometimes the receiving server rejects the message during the SMTP conversation. Other times the server accepts the message and later sends a failure notice. RFC 5321 says that once a server accepts a message, it takes responsibility for delivering it or reporting back if delivery fails.
A hard bounce is permanent. Sending the same message to the same address again will fail the same way. A soft bounce is temporary. The address may be fine, and a retry could work.
Some things look like bounces but are not:
- Out-of-office and auto-replies. The message was delivered. Postmark files these under a separate auto responder type, not as hard or soft bounces.
- Spam complaints. The message was delivered, and then the recipient marked it as spam. It is not a bounce, but Postmark deactivates the address just as it does for a hard bounce.
- A web "bounce rate." In web analytics, bounce rate means something else. Email bounce rate only measures delivery failures.
Also, "hard" and "soft" are labels that ESPs (email service providers) use. The SMTP standard does not use them. The standard has reply codes. Each provider maps those codes to its own categories, so always check the raw code behind the label.
SMTP reply codes: 4xx temporary vs 5xx permanent
Every SMTP reply starts with a three-digit code. The first digit is the verdict. Under RFC 5321, a 4yz reply means the command was refused but the problem is temporary, so the client should try again. A 5yz reply means the command was refused and the client should not repeat the same request.
The RFC gives a rule of thumb. A reply belongs in 4yz if repeating the exact same command could work later, with nothing changed on either side. If something has to change first (the address, your authentication, your content), the reply belongs in 5yz.
Enhanced status codes (RFC 3463)
Basic codes like 550 are vague. Enhanced status codes add detail in a class.subject.detail format. In RFC 3463, class 2 means success, 4 means a persistent transient failure, and 5 means a permanent failure. The middle digit tells you what area the problem is in:
- X.1.x: address problems. X.1.1 means the mailbox does not exist. X.1.2 means the domain cannot accept mail. X.1.3 means the address syntax is invalid.
- X.2.x: mailbox problems. X.2.2 means the mailbox is full.
- X.4.x: network and routing problems. X.4.1 (no answer from host) is meant only as a persistent transient error.
- X.7.x: security or policy problems. This is where authentication and spam blocks show up.
Common bounce codes and what to do
The reply text in this table comes from Google's list of Gmail SMTP errors. Other mailbox providers word things differently, but they use the same RFC 3463 code structure.
| Code | What it means | Type | What to do |
|---|---|---|---|
550 5.1.1 | The account does not exist (Gmail asks you to check for typos) | Hard, recipient side | Suppress now. Check the record for a typo and ask the user to fix it. |
5.1.2 | The destination domain does not exist or cannot accept mail | Hard, recipient side | Suppress. Usually a misspelled or expired domain. |
550 5.2.1 | The account is inactive | Hard, recipient side | Suppress. Ask for a new address through another channel. |
552 5.2.2 | The inbox is out of storage and the account is inactive | Hard, recipient side | Suppress. |
452 4.2.2 | The inbox is out of storage space | Soft, recipient side | Let your server retry. Suppress only if it keeps happening across sends. |
4.4.1 | No answer from the receiving host | Soft, network | Retry with backoff. Check whether one domain is down or all of them are. |
450 4.2.1 | Peak relay limit exceeded (Gmail marks this as temporary) | Soft, sender side | Slow down your sending rate. Do not suppress the recipient. |
552 5.3.4 | The message is over Google's size limit | Hard for this message, sender side | Make the message smaller. The address is fine. |
550 5.7.1 | The recipient or domain has a policy that blocks your message | Hard, often sender side | Check SPF, DKIM, DMARC, content and reputation before you remove anyone. |
550 5.7.40 | Your sending domain has no DMARC record or no DMARC policy | Hard, sender side | Publish a DMARC record, then resend. |
One more detail: Gmail uses 550 5.2.1 for two different things. It means an inactive account, and it also means a recipient receiving mail too fast to accept more. Read the text before you act.
Recipient-side vs sender-side bounces
This part is easy to miss. A 5xx code means "this request will not work as is." It does not always mean the address is dead.
- Recipient side: 5.1.1, 5.1.2, 5.2.1 (inactive). The data is bad. Suppress the address and fix the record.
- Sender side: 5.7.x policy blocks, 5.3.4 size limits, DMARC failures. Your setup is the problem. If you suppress these addresses, you lose good contacts and the real cause stays hidden.
Here is a quick test. If many unrelated recipients at one provider bounce with the same 5.7.x code in the same hour, the problem is your setup, not their addresses.
What ESPs do with each bounce type
Most sending platforms stop sending to hard-bounced addresses automatically. Here is how two of them describe it in their own docs.
| Event | Amazon SES | Postmark |
|---|---|---|
| Hard bounce | Added to the account-level suppression list, which is on by default for accounts that started after November 25, 2019. SES recommends against repeat attempts to hard-bounced addresses. | Deactivated automatically. The bounce webhook marks it as TypeCode 1. |
| Soft bounce | SES retries the message. It notifies you once it stops retrying. | Webhook TypeCode 4096. You check the Inactive flag to see whether the address was deactivated. Transient failures use TypeCode 2. |
| Spam complaint | Suppressed if your settings include complaints. | Deactivated automatically. |
| Counts toward bounce rate | Only hard bounces to domains you have not verified. Soft bounces, such as mailbox-full bounces, do not count. | See Postmark's docs for your account. |
One detail about SES matters for developers. Sends that your account-level list blocks do not count toward Reputation.BounceRate. Sends blocked by the SES global suppression list are treated as hard bounces and do count. Keep your own suppression list in sync, so your app never sends to those addresses at all.
Retry and suppression rules
How long to retry a soft bounce
Your sending server (MTA) handles retries for a single message. RFC 5321 says a sender must wait before retrying after a failure, and the wait should generally be at least 30 minutes. Retries should continue for at least 4 to 5 days before the server gives up. ESPs often set their own schedules, so check yours.
When a soft bounce should become a suppression
Retrying one message is different from deciding whether to keep mailing an address. No standard sets a number for that. Here is the policy we suggest as a starting point. Tune it with your own data.
- Suppress after three consecutive soft bounces on separate sends, if the reason stays the same (for example, mailbox full every time).
- Reset the count whenever a message to that address is delivered.
- Do not count sender-side deferrals (rate limits, 4.7.x) against the recipient.
- For important mail like password resets and receipts, show the user a message in your app instead of silently dropping the email.
When to suppress a hard bounce
For recipient-side codes (5.1.1, 5.1.2, inactive account), suppress on the first bounce. For 5.7.x policy codes, fix your setup first. Then send again to a small sample before you suppress anyone.
How email bounce rate is computed
The basic formula is:
bounce rate = (bounced messages / messages sent) x 100
Track hard bounce rate and soft bounce rate separately. A rise in soft bounces often points to throttling or a provider outage. A rise in hard bounces points to list quality. For example, 150 hard bounces out of 10,000 sends is a 1.5% hard bounce rate.
Your ESP may calculate it differently. Amazon SES counts only hard bounces to domains you have not verified. It measures them over a "representative volume" of your recent mail, not a fixed time window. SES also says that mail to verified addresses and to its inbox simulator is not counted. Its published levels are:
- Recommended: keep the bounce rate below 2%.
- 5% or more: the account is placed under review.
- 10% or more: SES may pause sending until you fix the cause.
Gmail and Yahoo sender requirements (2024 and later)
Gmail and Yahoo turn some sender mistakes into bounces. If your mail does not meet their rules, you can get 4xx deferrals or 5xx rejections even when every address on your list is valid.
| Requirement | Gmail | Yahoo |
|---|---|---|
| Applies from | February 1, 2024, for personal Gmail accounts | February 2024 |
| Authentication, all senders | SPF or DKIM | SPF or DKIM at a minimum |
| Authentication, bulk senders | Stricter rules above 5,000 messages a day, including authentication and easy unsubscribe (FAQ) | Both SPF and DKIM, plus a published DMARC policy |
| Spam rate | Below 0.3% in Postmaster Tools | Below 0.3% |
| DNS and transport | Valid forward and reverse DNS, TLS | Valid forward and reverse DNS |
| Standards | RFC 5322 message format | Comply with RFCs 5321 and 5322 |
| Unsubscribe | Easy unsubscribe for bulk senders | One-click unsubscribe for bulk senders, from June 2024 |
Google says that starting November 2025, Gmail is increasing enforcement against non-compliant mail, including temporary and permanent rejections. If you see a jump in 5.7.x bounces from Gmail, check your SPF, DKIM and DMARC before you look at the list.
What causes hard bounces at signup
Many hard bounces start at the signup form. Postmark says typos are the most common cause of hard bounces. The usual sources:
- Domain typos. gmial.com instead of gmail.com. Depending on the typo domain, you get a 5.1.2 bounce, a 5.1.1 bounce, or mail delivered to the wrong place.
- Dead or expired domains. A company that changed its name, or a domain that lapsed.
- Domains with no MX or A record. Nothing there can receive mail.
- Disposable inboxes. They accept mail for a while and then stop working, so later sends bounce.
- Mistyped usernames. jane.doe vs janedoe at a real provider. The domain is fine, but the mailbox does not exist.
What validation can and cannot catch
This is where we stand. ContactLint is a DNS-based check. It never opens an SMTP connection to the mailbox. Here is what that means in practice:
| Problem | Caught by a DNS-based check like ContactLint? | Notes |
|---|---|---|
| Invalid syntax | Yes | Checked against practical RFC syntax rules. |
| Domain with no MX or A record | Yes | The MX and A record lookups flag it. Try it with the MX record checker. |
| Typo of a major provider (gmial.com) | Yes | Returns a did_you_mean suggestion. See the list of typos it catches. |
| Disposable domain | Yes, if the domain is on the list | Test one with the disposable email checker. |
| Role address (info@, admin@) | Flagged | Role addresses are not always bounces. See role-based email detection. |
| Mailbox does not exist at a real domain (5.1.1) | No | Proving a mailbox exists requires talking to the mail server. |
| Catch-all domain | No | ContactLint cannot detect catch-all domains. |
| Mailbox full, policy blocks, sender reputation | No | These depend on the moment you send and on your setup. |
So validation at signup removes a whole category of hard bounces, but not all of them. You still need bounce handling. You also need double opt-in if you need to know the person actually owns the inbox.
A step-by-step bounce handling playbook
- Validate at the form. Check syntax, MX records, typos and disposable domains before you save the record. Show "Did you mean...?" instead of blocking the user.
- Send a confirmation email. A delivered confirmation is strong evidence that the address works.
- Capture every bounce event. Use your ESP's webhook or notifications. Store the SMTP code, the enhanced code, the raw text and a timestamp. A "hard" or "soft" label alone is not enough.
- Classify by code, not label. Use the first digit for temporary vs permanent. Use the middle digit to tell address problems (X.1, X.2) from policy problems (X.7).
- Suppress recipient-side hard bounces on the first occurrence. Write the suppression to your own database as well as to the ESP's list, so every sending path respects it.
- Route sender-side failures to engineering. 5.7.x spikes, DMARC errors and size limits are setup problems. Pause the affected stream, fix the cause, then send again to a small sample.
- Apply a soft bounce limit. Let the MTA retry each message. Suppress an address only after repeated soft bounces on separate sends.
- Tell the user in the app. If a transactional email hard bounces, ask the user to update their address the next time they log in.
- Watch rates weekly. Track hard and soft bounce rates by mailbox provider, plus your spam rate in Google Postmaster Tools.
- Validate before every import. Run CSV imports and CRM syncs through the same checks you use at signup before the first send.
How we put this together
We read the pages ranking in Google US for "hard bounce vs soft bounce" on October 18, 2026, and noted what they cover and what they leave out. Then we checked every rule and number against primary sources: RFC 5321 and RFC 3463, Google's Gmail help pages, the Yahoo Sender Hub, and the Amazon SES and Postmark docs, all linked above. We did not run send tests for this article. All claims about ContactLint come from our own product and pricing pages. The suggested soft bounce limit is our recommendation, not a published standard.
FAQ
What is a soft bounce?
A soft bounce is a temporary delivery failure. The receiving server answered with a 4xx code, such as 452 4.2.2 for a full mailbox, and the sending server will usually retry. The address may still be good.
What is a hard bounce?
A hard bounce is a permanent delivery failure, signaled by a 5xx code such as 550 5.1.1 for a mailbox that does not exist. Sending the same message to the same address again will fail the same way, so suppress the address.
How many soft bounces should happen before I suppress an address?
No standard sets a number. RFC 5321 says a sender should generally keep retrying one message for at least 4 to 5 days. A starting rule we suggest is to suppress after three consecutive soft bounces on separate sends, then adjust it based on your own data.
How is email bounce rate calculated?
Divide bounced messages by messages sent and multiply by 100. Track hard and soft bounces separately. Amazon SES counts only hard bounces to domains you have not verified, measured over a representative volume of your mail.
What bounce rate is too high?
Amazon SES recommends staying below 2%, places accounts under review at 5% or more, and may pause sending at 10% or more. Other providers set their own limits, so check the docs for the service you send through.
Can an email validation API prevent hard bounces?
It can stop the bounces caused by bad syntax, domain typos and domains with no mail records. A DNS based check like ContactLint cannot confirm that a specific mailbox exists or detect catch-all domains, so some 5.1.1 bounces will still happen.
How do Gmail and Yahoo sender rules affect bounces?
Since February 2024 both require authentication and a spam rate below 0.3%. Gmail says mail that fails its requirements can get temporary and permanent rejections, and those show up as bounces caused by your setup, not by the recipient.
What is the difference between a bounce and an out-of-office reply?
An out-of-office reply means the message was delivered and the mailbox sent an automatic response. It is not a bounce. Postmark, for example, files these under a separate auto responder type.
Stop hard bounces at the signup form
Many hard bounces start with a typo or a dead domain typed into a form. ContactLint checks syntax, MX and A records, disposable domains, role addresses and common typos in one API call. It does not connect to mail servers, so it cannot confirm that a mailbox exists or detect catch-all domains. You get 100 free checks a month, and credit packs start at $9 for 5,000 checks. You can read the API docs first or try the free email validation API page. When you are ready, get a free API key, no card needed.
Get a free API key. 100 checks per month, no card required.