What is an email bounce?
An email bounce is an email that could not be delivered and was refused or returned to the sender. The failure is reported through SMTP (Simple Mail Transfer Protocol) in one of two ways: the receiving server rejects the message during the SMTP conversation with a reply code, or it accepts the message, fails later and sends a delivery status notification (a bounce message) to the envelope sender, the Return-Path address.
Bounces come in two kinds. A hard bounce is permanent: the reply starts with 5, such as 550 5.1.1 (the mailbox doesn't exist) or 5.1.2 (the destination domain is bad), and sending again fails the same way. A soft bounce is temporary: the reply starts with 4, such as 421 (service not available), 450 or 451 (try again later) or 452 (insufficient storage), and the sending server keeps the message queued and retries, typically for days, before turning it into a final failure. The enhanced status code after the basic code (class.subject.detail, defined in RFC 3463) says what actually went wrong.
Policy rejections blur the line. A 5.7.x code means the receiver refused the message on policy grounds, often failed authentication under SPF, DKIM and DMARC, a blocked sending IP or content judged as spam, so the address itself may be perfectly valid. Treat these as a sender problem to fix rather than a reason to drop the contact. Taken together, bounces are email's equivalent of an SMS Delivery Report marked failed or a WhatsApp failed Message Status: the signal that a message did not arrive, and whether trying again could help.
Key takeaways
- An email bounce is a message the receiving side refused or returned undelivered, reported with an SMTP reply code.
- 5xx codes are permanent failures (hard bounces); 4xx codes are temporary (soft bounces) and are retried by the sending server.
- Suppress a hard-bounced address at once, and a soft-bouncing one only after repeated failures across several days.
- Keep bounce rate under about 2% of sends; rates approaching 5–10% put sending accounts and domain reputation at risk.
- A bounce is email's delivery-failure signal, the counterpart of a failed SMS delivery report or a WhatsApp failed status.
Where does your bounce rate sit?
- Healthy0.0–2.0%
- Investigate2.0–5.0%
- Account at risk5.0–10.0%
- Sending paused10.0–12.0%
Purchased list
11.0%
Mostly invalid or trap addresses: sending can be paused and the domain's reputation damaged.
Purchased list: 11.0% — Sending paused zone. Mostly invalid or trap addresses: sending can be paused and the domain's reputation damaged.
How does an email bounce work?
The sending server connects
Your mail server or email service opens an SMTP session with the recipient domain's MX host and offers the message.
The receiver answers with a code
A 2xx reply means accepted, 4xx means try later and 5xx means refused. The enhanced code, such as
5.1.1or4.2.2, narrows down the reason.Soft bounces are retried
On a 4xx, the sender keeps the message queued and tries again at intervals. RFC 5321 suggests at least 30 minutes between attempts and a give-up time of at least four to five days.
Late failures come back as bounce messages
If the receiver accepted the message but can't deliver it, it emails a delivery status notification (an RFC 3464
multipart/report) to the Return-Path address.Your system classifies and suppresses
Parse the code from the SMTP reply, the bounce message or your email service's bounce webhook, record it against the contact and add hard-bounced addresses to your Suppression List.
An email bounce in code
// Turn an SMTP reply or DSN diagnostic into an action.export function classifyBounce(reply) {// e.g. "550 5.1.1 <asha@example.com>: Recipient address rejected: User unknown"const basic = /^([245])\d\d/.exec(reply)?.[1];const enhanced = /\b([245])\.(\d{1,3})\.(\d{1,3})\b/.exec(reply);const cls = enhanced?.[1] ?? basic;const subject = enhanced ? `${enhanced[2]}.${enhanced[3]}` : null;if (cls === "2") return { type: "delivered" };if (cls === "4") return { type: "soft", suppress: false }; // let the MTA retry; count repeatsif (cls === "5" && subject?.startsWith("7.")) return { type: "policy", suppress: false }; // fix SPF/DKIM/DMARC, IP or contentif (cls === "5") return { type: "hard", suppress: true }; // 5.1.1, 5.1.2 ... never retryreturn { type: "unknown", suppress: false };}export function onBounce(contact, reply) {const b = classifyBounce(reply);if (b.suppress) return suppression.add(contact.email, { reason: reply, at: new Date() });if (b.type === "delivered") contact.softBounces = 0; // a success resets the runif (b.type === "soft" && (contact.softBounces = (contact.softBounces ?? 0) + 1) >= 5) return suppression.add(contact.email, { reason: "repeated soft bounces" });}
Policy (5.7.x) rejections are sender problems, so they are logged and fixed rather than suppressed. Tune the soft-bounce threshold to your sending frequency.
Key facts at a glance
An email bounce: key facts and limits
- Hard bounce
- Permanent failure, 5xx reply (e.g. 550 5.1.1 user unknown)
- Soft bounce
- Temporary failure, 4xx reply (e.g. 421, 451, 452)
- Enhanced status codes
- class.subject.detail, defined in RFC 3463
- Policy rejections
- 5.7.x: authentication, reputation or content refused
- Retry window
- RFC 5321: give up after at least 4–5 days
- Bounce message format
- RFC 3464 delivery status notification
- Healthy bounce rate
- Under about 2% of sends (rule of thumb)
Why does an email bounce matter?
Mailbox providers judge senders by how often they hit addresses that don't exist. A list full of stale addresses pushes the bounce rate up, which drags down sender reputation, and with it inbox placement for everything else you send, including password resets and invoices. Handling bounces properly (suppressing hard bounces immediately, retrying soft ones sensibly and fixing policy rejections at the source) is one of the cheapest ways to protect Deliverability, and it keeps reporting honest when email, SMS and WhatsApp campaigns are compared side by side.
Common wrong turns
Common mistakes with an email bounce
Retrying hard bounces
Sending again to an address that returned 5.1.1 just adds another hard bounce. Suppress it on the first one, and re-add it only if the person gives you the address again.
Deleting contacts on policy bounces
A 5.7.x rejection usually means your authentication or reputation failed, not the address. Fix SPF, DKIM and DMARC alignment, or the blocked IP, before you touch the list.
Ignoring soft bounces forever
An address that soft-bounces on every send for weeks is effectively dead, such as a full, abandoned mailbox. Suppress after a run of consecutive soft bounces, for example three to five across several days.
Mailing old or bought lists
Stale and purchased lists cause bounce spikes and spam-trap hits that can get a domain blocked. Re-confirm old contacts in small batches and never buy lists.
Counting accepted as delivered
A 250 from the receiving server means accepted, not inboxed, and late bounce messages can still arrive. Reconcile asynchronous bounces before reporting delivery.
Example: A Bengaluru edtech's re-engagement email
A Bengaluru edtech company emails 80,000 learners who haven't heard from it in 18 months. The first batch of 10,000 bounces at 7.8%, almost all 550 5.1.1 user-unknown replies, and one mailbox provider starts deferring with 4xx codes. The team stops the send, suppresses every hard bounce, and re-confirms the rest in small daily batches with a clear "still want course updates?" email. Two weeks later its bounce rate is back near 1%. Learners whose email bounced but who had opted in to WhatsApp get the course reminder there as a utility template instead (figures illustrative).
Good practice
Best practices for an email bounce
- Confirm addresses at capture with a Double Opt-in email.
- Use a dedicated bounce address or VERP so every bounce maps back to one recipient.
- Watch bounce rate per mailbox provider; a spike at one provider usually means a block, not bad data.
- Share one suppression list across marketing and transactional streams.