Mastering Soft Bounce vs Hard Bounce in Emails

18 min read

Learn the difference between soft bounce vs hard bounce. Master SMTP codes, retries, & suppression lists for robust AI email workflows.

John Joubert

John Joubert

Founder, Robotomail

Mastering Soft Bounce vs Hard Bounce in Emails
Table of contents

Your agent shipped. It can draft replies, send onboarding emails, follow up on stale leads, and push account alerts without a human touching the keyboard. Then the bounce events start coming in.

At first, they look like noise. A few undelivered messages. A mailbox full here, an invalid recipient there. If your system treats all of them the same, it will make the wrong decision in both directions. It will keep retrying dead addresses forever, and it will give up too early on addresses that would have recovered on the next attempt.

That's the soft bounce vs hard bounce problem for autonomous systems. This isn't a campaign reporting detail. It's control-plane logic. Your agent needs to decide whether to retry, suppress, quarantine, alert, or stop sending entirely, and it needs to do that from machine-readable delivery feedback instead of intuition.

Why Email Bounces Are Critical Feedback for Your AI Agent

A developer usually notices bounces only after something else breaks first. Password reset emails stop reaching some users. Sales follow-ups look “sent” in logs but never land. A support agent keeps trying the same contact and unwittingly burns sender reputation.

That happens because a bounce isn't just a failed email. It's a structured response from the receiving side telling your system what went wrong. If you ignore it, your agent loses the feedback loop that keeps outbound mail healthy.

Autonomous systems fail differently

A marketer might review a report once a day and clean a list manually. An AI agent doesn't work like that. It can retry in minutes, fan out across many recipients, and keep acting on stale assumptions unless you encode limits.

For agent builders, bounce handling needs to answer operational questions:

  • Should this address be retried because the destination might recover?
  • Should it be suppressed immediately because the failure is permanent?
  • Should the agent pause a workflow because delivery uncertainty changes the next action?
  • Should an alert fire because a pattern suggests infrastructure trouble instead of recipient trouble?

Practical rule: Treat every bounce as input to state management, not as a log line.

What goes wrong when you ignore them

The damage isn't theoretical. Repeated sends to bad addresses tell mailbox providers that your system doesn't manage recipient quality. Repeated retries to temporarily failing servers can look abusive if your agent has no brakes. Both patterns reduce deliverability for mail that matters.

The distinction is simple at a high level. A hard bounce means the address or destination is effectively unusable. A soft bounce means delivery failed for now, but the address may still be valid. That one difference drives every downstream decision your agent should make.

Here's the quick comparison you need in code and in operations:

Signal Hard bounce Soft bounce
Failure type Permanent Temporary
Retry policy No retry Retry with limits
Address status Suppress Keep under observation
Typical agent action Mark invalid and block future sends Back off, retry, then escalate if repeated
Risk if mishandled Sender reputation damage from repeated sends to dead addresses Infinite retries, queue churn, and avoidable suppression

Hard Bounces and Soft Bounces Defined

Your agent sends a signup confirmation, gets a bounce, and has to choose the next action without a human in the loop. That choice is the difference between a clean suppression decision and a retry loop that keeps burning API calls, queue capacity, and sender reputation.

A hard bounce and a soft bounce are both delivery failures. They are different failure classes, and your automation should treat them differently from the first event.

An infographic comparing hard bounces and soft bounces to explain email delivery failures and their solutions.

What counts as a hard bounce

A hard bounce means the destination is not usable for delivery under current conditions. In practice, that usually means the mailbox does not exist, the domain is invalid, or the receiving side has issued a permanent rejection.

Common examples include:

  • User unknown because the local part is mistyped, deleted, or never existed
  • Domain not found because the address points to a non-existent destination
  • Policy rejection marked permanent because the receiver will not accept that message or recipient

For an autonomous system, the default action is suppression. Stop future sends to that recipient, record the reason, and require a fresh signal before you allow another attempt. If you skip that guardrail, an agent can keep rediscovering the same bad address through multiple workflows and turn one invalid contact into repeated reputation damage.

What counts as a soft bounce

A soft bounce means delivery failed for now, but the address may still be valid. Typical causes include a full mailbox, a receiving server that is temporarily unavailable, rate limiting, or a message that exceeded a size limit.

This is where delivery mechanics matter. If you need a quick refresher on the path a message takes before it bounces, review how email delivery works from send to receipt.

A soft bounce should not trigger immediate suppression. It should trigger controlled retry behavior. Controlled matters. AI agents are good at persistence, and persistence without limits turns temporary failure into self-inflicted abuse. Set retry ceilings, backoff intervals, and expiration windows so the system eventually stops and escalates or marks the address for review.

The distinction developers actually need

The practical question is not whether mail failed. The practical question is what the failure allows your system to do next.

A hard bounce answers: should this address ever be tried again without new input?
A soft bounce answers: is another attempt reasonable, and under what limits?

That difference drives system design:

  • Hard bounce: mark invalid, suppress future sends, fan that status out to every workflow that could reuse the address
  • Soft bounce: retain the address, schedule bounded retries, and watch for repeated failures that suggest the condition is no longer temporary

A dead mailbox and a busy mailbox produce the same top-level outcome, undelivered mail. They do not create the same operational risk. One calls for suppression. The other calls for restraint.

Decoding Bounce Messages with SMTP Codes and DSNs

A bounce event becomes useful when your system reads the details, not just the headline.

Under the hood, delivery failures usually arrive with SMTP response information and DSN data. That's what lets software distinguish a temporary refusal from a permanent one. If you haven't looked closely at how mail transport works, this is a good point to review how an email works before wiring classification logic.

The code ranges that matter

A hard bounce represents a permanent delivery failure occurring when an email address is invalid, non-existent, deleted, or the receiving server has permanently rejected the message, typically indicated by SMTP error codes in the 5XX range. In contrast, a soft bounce signifies a temporary failure where the message reaches the recipient's server but is deferred due to short-term issues like a full inbox, server downtime, or rate limiting, identified by SMTP 4XX codes, as described in MessageFlow's breakdown of bounce behavior.

That single split is the first classifier your agent should apply:

  • 4XX usually means temporary failure
  • 5XX usually means permanent failure

“Usually” matters. Real mail systems aren't perfectly tidy. Some providers phrase similar problems differently, and some DSNs contain useful text that should influence classification.

Common SMTP bounce codes

Code Meaning Bounce Type
421 Service not available, transmission channel issue, or temporary server problem Soft bounce
450 Mailbox unavailable for now, often due to temporary conditions Soft bounce
452 Insufficient system storage or temporary capacity issue Soft bounce
550 Mailbox unavailable, often user unknown or rejected permanently Hard bounce
551 User not local or mailbox issue requiring rerouting Hard bounce
552 Storage allocation issue or message constraints, often treated as permanent in many implementations Hard bounce

Why DSNs matter beyond the first digit

If your parser only checks whether a code starts with 4 or 5, it will miss edge cases that matter operationally.

A mailbox-full condition is a good example. It's temporary in concept, but the surrounding message can tell you whether you should retry soon, retry cautiously, or stop after repeated failures. The DSN often includes reason text that lets you separate “server down right now” from “recipient keeps rejecting oversized content” from “recipient policy block.”

Use a layered approach:

  1. Read the SMTP range first to get a baseline classification.
  2. Inspect DSN reason text for stronger signals such as invalid recipient versus temporary capacity issue.
  3. Store normalized cause categories in your own system so later retries don't depend on raw text parsing every time.
  4. Preserve the original payload for debugging, because classification mistakes usually show up first in edge-case DSNs.

If your event model only stores bounced = true, you've thrown away the data your agent needs to behave safely.

A mature mail pipeline doesn't just record that delivery failed. It records why it failed, whether the reason is stable, and what policy should fire next.

Building Bounce Classification Logic for Your Agent

The naive implementation is a one-liner: 5xx means hard bounce, 4xx means soft bounce. That gets you started, but it won't protect an autonomous system for long.

Agents don't fail because they can't classify the first bounce. They fail because they keep making the same bad decision over time.

A flowchart showing the process of classifying SMTP email bounces into hard and soft bounce categories.

State matters more than the first event

A single soft bounce rarely tells you enough. The receiving server might be overloaded. The inbox might be full for a day. The problem might disappear on the next retry.

What matters is the pattern.

A frequently asked but poorly answered question is whether repeated soft bounces automatically convert to hard bounces. A recent 2025 industry analysis says 68% of platforms now auto-suppress after 4 soft bounces within 7 days, but that threshold varies by provider and sender reputation score, according to Braze's discussion of hard and soft bounces. That matters for agent developers because an AI agent may retry indefinitely unless you explicitly cap it.

A better classification model

Instead of modeling just two terminal states, use a small state machine:

  • Deliverable
  • Soft-bounced
  • Quarantined
  • Hard-bounced
  • Manually restored if a user later corrects the address

That gives your system room to react without jumping straight from “healthy” to “dead.”

What to evaluate on each bounce

When your webhook or event consumer receives a bounce, evaluate at least these signals:

  • Code family. Start with 4xx versus 5xx.
  • Normalized reason. Invalid recipient, mailbox full, rate limit, server unavailable, policy rejection.
  • Consecutive history. Has this same address failed repeatedly without a successful delivery in between?
  • Time window. Three soft bounces spread over weeks is different from repeated failures in hours.
  • Workflow criticality. A password reset should retry faster than a low-priority nurture message.

What not to do

Don't let the agent make stateless retry decisions. That's how you end up hammering the same unreachable destination because every attempt is evaluated in isolation.

Don't convert all repeated soft bounces into hard bounces instantly either. Some addresses are valid but intermittently unavailable, and your system should preserve that distinction internally even if it suppresses future sends operationally.

Build for reversible decisions where possible. Suppression is operational. “This address is permanently invalid” is a data claim. Those are not always the same thing.

Practical decision shape

A solid implementation often looks like this:

Condition Recommended classification Action
5xx with invalid recipient style reason Hard bounce Suppress immediately
4xx with transient infrastructure reason Soft bounce Retry with backoff
Repeated soft bounces in a short window Quarantine or suppress Stop autonomous retries
Ambiguous reason text Undetermined Hold for review or conservative retry policy

That last row matters more than anticipated. Real email systems produce messy signals. “Undetermined” is a legitimate state, and it's safer than pretending every bounce fits a clean binary rule.

A Strategic Framework for Handling Bounces

Your agent sends a follow-up, gets a temporary failure, retries, gets queued again by another workflow, and keeps going because each task only sees its own local state. A human would spot the pattern and stop. Your system needs to do the same.

A flowchart showing the bounce management strategy for handling both hard and soft email delivery failures.

The practical goal is simple. Prevent invalid addresses from being retried, prevent temporary failures from turning into spammy behavior, and keep one noisy recipient from dragging down the reputation of the whole sending system.

Rule one for hard bounces

Treat a confirmed hard bounce as a terminal event for autonomous sending. Once the destination says the recipient does not exist, the only safe default is to stop.

Your application should do three things immediately:

  • Suppress the address across all workflows, not just the job that triggered the bounce
  • Store the failure details so support, ops, or later automation can see the SMTP code and provider message
  • Mark email as unavailable for downstream logic, so the agent chooses another channel or ends the task

This needs to happen in the hot path, not in a nightly cleanup process. If suppression lags by even a few minutes, parallel workers can keep sending to the same bad address.

That is how AI agents create avoidable reputation problems. They scale mistakes faster than human operators.

Rule two for soft bounces

Soft bounces need patience and limits. Retry behavior should be explicit, bounded, and tied to recipient history.

A good default is a capped retry schedule with increasing delays:

  1. Retry once after a short delay for transient issues like mailbox lock or temporary destination trouble
  2. Retry again after a longer delay if the reason still looks temporary
  3. Stop autonomous retries after the final attempt and move the address into a separate state

The point is not to maximize delivery at any cost. The point is to give valid addresses a chance to recover without teaching your agent to keep knocking on a closed door.

Guidance often cited in email operations recommends limited retries for soft bounces and suppression after repeated consecutive failures, as noted earlier. That pattern matches real infrastructure trade-offs. A few retries recover temporary issues. Unbounded retries create noise, waste capacity, and raise abuse signals.

Here's a policy map that works well for agent-driven systems:

Bounce type Immediate action Follow-up
Hard Suppress address Block future sends unless the address is corrected
Soft, first event Keep active Retry with backoff
Soft, repeated Quarantine Stop new workflow-triggered sends
Soft, chronic Suppress operationally Require review or later reactivation logic

Why quarantine matters

Quarantine solves the gap between “retry” and “delete.” That gap matters a lot in autonomous systems.

Some addresses are valid but temporarily unusable. A full suppression record makes recovery harder than it needs to be. Blind retries are worse. Quarantine gives your agent a third option: stop sending for now, keep the state visible, and require a timer, a recovery signal, or a human decision before the address returns to rotation.

I recommend treating quarantine as an operational status, not a statement that the address is bad data forever. That distinction keeps your contact model honest and your retry logic safe.

A quarantined address also should not be reactivated by accident because a different agent, queue, or product feature creates a new send request. Central suppression and quarantine checks must sit in front of every outbound email path.

A short explainer helps if you're sharing this policy with product or support teams:

What holds up in production

These patterns hold up:

  • Immediate hard-bounce suppression
  • Bounded soft-bounce retries with backoff
  • Shared recipient state across agents, queues, and workflows
  • Quarantine before full suppression for repeated temporary failures
  • Content and authentication checks alongside bounce handling, including Intelligent Contacts' email advice

These patterns fail fast:

  • Retries decided per job with no shared history
  • A fresh workflow bypassing an existing suppression record
  • Treating all soft bounces as harmless
  • Treating all repeated soft bounces as permanent data errors
  • Letting the agent optimize for task completion while ignoring sender reputation

Keep one rule above the rest. Bounce history has to outrank task urgency, or your agent will eventually trade short-term delivery attempts for long-term deliverability loss.

Monitoring Your System's Email Health

Handling individual bounces correctly isn't enough. You also need system-level visibility, because sender health degrades gradually and then fails all at once.

Dashboard displaying key email system health metrics including total, hard, and soft bounce rates with trend visualization.

The threshold that actually matters

The accepted industry benchmark for acceptable email bounce rates is 2%, meaning only two out of every hundred emails should return as undelivered. Between 2% and 5% is a warning zone, and anything above 5% requires immediate corrective action such as scrubbing contact lists or reevaluating email design, according to Emma's bounce rate benchmark summary.

For engineering teams, that turns bounce monitoring into an alerting problem.

Track these views continuously:

  • Total bounce rate to know whether your overall sending is stable
  • Hard bounce trend to catch data quality regressions
  • Soft bounce trend to catch throttling, temporary destination issues, or bad retry policy
  • Bounce reasons by category so you can separate invalid addresses from content or infrastructure issues

What to do when the graph moves

If total bounce rate enters the warning zone, don't just look at the aggregate. Break it down by sender, workflow, recipient source, and bounce class.

A spike in hard bounces usually points to bad address collection or stale records. A spike in soft bounces often points to temporary server-side issues, pacing problems, oversized messages, or policy friction on the receiving side.

Useful supporting practices often overlap with spam prevention. If you want a compact operations checklist, Intelligent Contacts' email advice is worth reviewing because it ties authentication, content quality, and sender behavior together in practical terms.

Build your dashboard around decisions

A dashboard is useful only if it tells the team what action to take next.

I'd put these questions directly into the monitoring design:

  • Is this a recipient-quality problem or a sending-behavior problem?
  • Did one agent, mailbox, or workflow cause the change?
  • Are suppressions firing correctly, or are bad addresses still receiving attempts?
  • Did a recent product change alter message size, cadence, or targeting?

Watch trend lines, not just snapshots. Bounce spikes are obvious. slow drift is what usually damages reputation first.

You should also keep authentication health in the same operational view. Strong SPF, DKIM, and DMARC posture won't eliminate all bounces, but it reduces the chance that picky receivers reject or distrust otherwise legitimate mail. For agent systems, sender identity is part of reliability, not just compliance.

Implementing Bounce Handling with Robotomail

If you're wiring this into an agent stack, the practical objective is simple: receive a bounce event, verify it, update recipient state, and stop bad decisions from repeating. A useful starting point is Robotomail's guide to handling bounce back messages.

Robotomail is purpose-built for AI agents, so the integration model fits this workflow well. Developers can create mailboxes programmatically, send with a straightforward API, and handle inbound events through webhooks, server-sent events, or polling. Event payloads are HMAC-signed for integrity, which matters when bounce state changes can suppress future sends.

The implementation shape

At a high level, your webhook handler should do four things:

  1. Verify the signature before trusting the event.
  2. Identify the recipient and mailbox context in your application.
  3. Read the bounce classification data and normalize it into your own recipient state model.
  4. Apply policy such as suppressing, quarantining, or scheduling a retry.

A conceptual flow looks like this:

  • Receive email.bounced
  • Verify HMAC signature
  • Inspect bounce type and metadata
  • If hard bounce, mark recipient invalid and block future sends
  • If soft bounce, increment retry history and decide whether to retry, quarantine, or suppress

Why abstraction helps

The biggest operational win is not having to build your whole system around parsing raw DSNs by hand. Your application can react to a cleaner event model and still preserve the raw evidence for debugging when classification gets messy.

That's what you want in an autonomous environment. The agent shouldn't need to understand the full complexity of email transport. It should receive a trusted event, update durable state, and follow a strict policy that prevents infinite retries and accidental reputation damage.


Robotomail gives agent builders an email stack that matches how autonomous systems work. You can provision real mailboxes through API, send and receive without SMTP setup or OAuth friction, use custom domains with auto-configured DKIM, SPF, and DMARC, and consume signed events through webhooks, SSE, or polling. If you're building email-enabled agents and want the mailbox layer to behave like the rest of your infrastructure, Robotomail is worth a close look.

Give your AI agent a real email address

One API call creates a mailbox with full send and receive. Webhooks for inbound, automatic threading, deliverability handled. 30-day money-back guarantee.

Related posts