Skip to main content
MailCub Logo Image
Guidelines

Hard Bounce vs Soft Bounce: Retry Strategy That Works

By MailCub TeamFeb 24, 202610 min read

When transactional emails fail, many systems make one of two mistakes: they either retry forever or suppress too early. Both approaches create problems. Endless retries waste capacity and can hurt sender reputation, while early suppression can block real users from receiving OTPs and password resets.

This guide gives SaaS and development teams a practical, deterministic policy for bounce handling. You will learn how to classify hard bounce vs soft bounce failures using SMTP reply codes (4xx vs 5xx), how enhanced status codes improve classification (including mailbox full cases), and how to build a capped retry strategy that behaves safely across providers.

You will also see how to store bounce evidence for debugging, how to build a suppression list with guardrails, and how delivery logs plus event tracking fit into production monitoring. If you are implementing this on MailCub, the MailCub Documentation and the Transactional Email Service are the right places to connect your sending flow, logs, and webhook-style event tracking. You can review MailCub Pricing if you are planning higher sending volume.

Quick Answer

  • SMTP 5xx is usually permanent, so treat it as a hard bounce and suppress the recipient for that message flow.
  • SMTP 4xx is usually temporary, so treat it as a soft bounce and retry with backoff.
  • Use enhanced status codes to refine decisions (for example, mailbox full X.2.2 / 4.2.2 should retry more slowly).
  • Cap retries with both an attempt limit and a total time window.
  • Store the raw reason and your normalized classification so issues stay debuggable.
  • Use logs and webhook/event updates to keep message state accurate asynchronously.

Why It Matters

Bounces are not random noise. They are operational signals that tell you about invalid addresses, temporary throttles, policy blocks, or mailbox limits. SMTP already gives you the core distinction: 4xx is transient and retryable, while 5xx is permanent and should not be repeated as-is.

If you ignore that difference, you will either hammer recipient servers with pointless retries or block legitimate users after a temporary issue. A good bounce strategy reduces support tickets and helps maintain healthier sender reputation over time.

Hard Bounce vs Soft Bounce Classification Rules You Can Code

SMTP reply codes provide the baseline policy:

  • 4yz = transient negative completion (retryable)
  • 5yz = permanent negative completion (do not repeat the same request as-is)

Enhanced status codes add precision. They use a structured format and help your system make better decisions when the SMTP text is vague. For example, mailbox full is documented as X.2.2, which should be treated as a persistent transient failure. That means retryable, but not aggressively.

Input signal Treat as Action
SMTP 5xx (e.g., 550) Hard bounce Suppress recipient; stop retries for this message
SMTP 4xx (e.g., 421/451/452) Soft bounce Retry with backoff; keep queued
Enhanced 4.2.2 / X.2.2 mailbox full Soft bounce (persistent) Retry slower; cap attempts; optionally notify user
Provider “HardBounce” event Hard bounce Add to suppression; investigate spikes
Provider “SoftBounce/Transient” event Soft bounce Retry policy + monitoring; don’t suppress immediately

Step-by-Step Solution

1) Capture bounce signals consistently (SMTP + provider events)

You need both raw protocol evidence and provider event outcomes:

  • Raw SMTP/DSN codes and message text for debugging and forensics
  • Provider events for asynchronous delivery outcomes

Store fields like smtp_code, enhanced_code, provider_event, raw_reason, message_id, and recipient_domain. MailCub’s transactional email workflow is a strong fit for this because it supports logs, analytics visibility, and webhook-style event tracking via the Transactional Email Service.

2) Normalize into a simple message state model

Keep the state model small and consistent:

  • DELIVERED
  • DEFERRED (retry scheduled)
  • BOUNCED_HARD (suppressed)
  • BOUNCED_SOFT (retryable, limited)
  • BLOCKED_POLICY (manual review threshold)

Do not overfit to many vendor-specific labels. Keep raw reason strings in storage so you can still group and analyze patterns later.

3) Apply defaults: 4xx retry, 5xx suppress

Use SMTP semantics as your default behavior:

  • 4xx → retry with backoff
  • 5xx → suppress and stop repeating the same request

This gives you a predictable baseline and avoids the most common retry and suppression mistakes.

4) Refine soft bounces with enhanced status codes

Enhanced status codes help you avoid blunt decisions. If you see mailbox full (X.2.2 / 4.2.2), keep it retryable, but slow the schedule. If you see repeated temporary failures for the same domain, reduce concurrency and widen backoff for that domain.

This is where an evidence-based workflow matters. Use the MailCub Documentation to connect your API send flow with logs and event capture so your bounce rules are based on actual outcomes.

5) Use a capped retry schedule (safe default)

A practical default retry schedule for transactional email:

  • Attempt 1: now
  • Attempt 2: +5 minutes
  • Attempt 3: +15 minutes
  • Attempt 4: +1 hour
  • Attempt 5: +6 hours

Stop after 5 attempts or 24 hours, whichever comes first. For mailbox full cases, make retries slower to avoid retry storms and unnecessary pressure on recipient servers.

6) Build suppression with guardrails

Suppress on clear hard bounces (5xx). Do not suppress after a single soft bounce. Instead, escalate to suppression only when you have stronger evidence, such as repeated 4xx failures over a longer window plus enhanced codes or provider events indicating persistent failure.

Keep suppression metadata so you can review and remove suppression safely after manual verification when needed.

7) Monitor bounce rates like production metrics

Track bounce behavior the same way you track other production issues:

  • Hard bounce rate (overall and by domain)
  • Soft bounce/defer rate (overall and by domain)
  • Retry queue depth and queue age
  • Complaint rate (if available)

Alert on sudden spikes, not small noise. Use logs and events to quickly find shared patterns across domains, templates, or sender identities. This is much easier when your logs and events are centralized through the MailCub Documentation integration model.

Common Mistakes

  • Retrying 5xx responses as if they were temporary.
  • Suppressing after one 4xx deferral, even though greylisting and temporary overload are common.
  • No retry caps, which creates infinite retries and reputation damage.
  • Not saving raw reason strings, making trend analysis difficult later.
  • Treating “accepted by API” as “delivered.”

Troubleshooting

Soft bounces increased overnight

Check whether the spike is concentrated to one recipient domain. Confirm your retry interval is not too aggressive. Look for mailbox full (4.2.2 / X.2.2) patterns and slow the retry schedule for those cases.

Hard bounces for addresses you believe are valid

Confirm the response is truly a 5xx permanent failure and not a temporary policy or filtering issue. Compare the SMTP result with provider classification if available (for example, HardBounce vs Transient in event streams).

Use delivery logs and event evidence before changing templates or retry rules. In many cases, the root cause is classification or suppression logic rather than content.

FAQ

What is a hard bounce vs soft bounce?

Hard bounces are generally permanent failures, often represented by 5xx SMTP replies. Soft bounces are temporary failures, often represented by 4xx replies, and may succeed on retry.

Should I retry SMTP 550 errors?

Usually no. SMTP 5xx is generally permanent and should not be repeated as-is in the same sequence.

How many retries should I do for soft bounces?

Use capped retries, such as up to 5 attempts or 24 hours, with backoff. Slow retries further for mailbox full (X.2.2 / 4.2.2).

What does SMTP 4xx vs 5xx mean?

SMTP 4xx means transient negative completion and is typically retryable. SMTP 5xx means permanent negative completion and should usually not be retried as-is.

What is enhanced status code 4.2.2?

It indicates mailbox full (X.2.2) and should be treated as a persistent transient failure. It is retryable, but your system should retry more slowly.

Should I suppress after one soft bounce?

No. Soft bounces can be temporary. Suppressing after one soft bounce can block valid users from receiving important messages.

How do webhooks help with bounce handling?

Webhooks deliver asynchronous outcomes such as bounces and deferrals so your app can update message state and suppression lists without relying only on polling.

Conclusion

A reliable bounce-handling system stays simple: classify using SMTP semantics, refine with enhanced status codes, cap retries, and suppress only when there is strong evidence.

This gives you predictable behavior across providers, fewer “email not received” tickets, and better sender reputation hygiene because you avoid pointless retries and repeated failures.

To implement this cleanly, use the MailCub Documentation for API, logging, and event integration, and the Transactional Email Service for transactional email workflows. If you are comparing plans for production scale, review MailCub Pricing.

Tags:
hard bounce vs soft bounceemail bounce handlingSMTP 4xx vs 5xxenhanced status codesbounce webhooksuppression listretry strategyexponential backoffgreylistingmailbox full 4.2.2deliverability monitoringMailCub Documentation

You Might Also Like