Menu
Accedi Crea account
Deliverability

SMTP Bounce Codes: How to Read Them Right (90% Get This Wrong)

Most teams misread SMTP bounce codes and end up retrying messages that will never deliver, or worse, killing their sender reputation. Here is what those three-digit numbers actually mean.

12 Nov 2024 · 6 min read · Target SMTP

Every transactional email system eventually produces a bounce log full of numbers nobody really reads. The team treats 550 the same as 421, retries everything three times, and wonders why their sender reputation is shrinking. SMTP status codes are not folklore: they are a precise contract between mail servers, and reading them correctly is the difference between a healthy pipeline and a slow-motion deliverability disaster.

In this guide we will decode the three-digit codes, the enhanced status codes defined in RFC 3463, and the typical real-world responses you will see from Gmail, Outlook, iCloud and the major Italian providers. By the end you will know exactly which bounces to retry, which to suppress, and which require human intervention.

The Anatomy of an SMTP Reply

An SMTP reply is made of three parts: a three-digit basic code, an optional enhanced status code (X.Y.Z), and a free-form text message. The basic code is the only one your retry logic should branch on. The enhanced code is for diagnostics. The text is for humans.

550 5.1.1 The email account that you tried to reach does not exist.

The first digit is the class of response. The second digit tells you the broad category. The third is a specific subcode. Here is the layout you must memorise:

First digitMeaningWhat to do
2xxSuccessNothing; message accepted
3xxIntermediate (waiting for more input)Continue the SMTP conversation
4xxTransient failureRetry with backoff
5xxPermanent failureSuppress, do not retry

This is the single most violated rule in homemade mail senders: 5xx means permanent, period. If you retry a 550 twenty times you are telling the receiver you are either misconfigured or malicious. Both interpretations end the same way: your IP gets throttled.

Hard Bounces vs Soft Bounces

A hard bounce is a 5xx response. The mailbox does not exist, the domain is invalid, or the receiver has flat-out refused you. A soft bounce is a 4xx response: mailbox full, server temporarily down, rate-limited, greylisted. The right behaviour is asymmetric.

  • Hard bounce: add the recipient to a suppression list immediately. Never send to that address again until it is manually re-validated.
  • Soft bounce: retry with exponential backoff for up to 72 hours, then promote to hard bounce.

Even one or two sends to a confirmed dead address will hurt your reputation. Major receivers keep histograms of how aggressively senders retry permanent failures, and aggressive retries are a strong spam signal.

The Enhanced Status Codes That Actually Matter

RFC 3463 added the X.Y.Z extended codes so you can distinguish a quota issue from a policy issue without parsing English prose. Here are the ones you will see most often:

Enhanced codeMeaningTypical text
5.1.1Mailbox does not exist"User unknown"
5.1.2Bad destination system"Domain not found"
5.2.2Mailbox full"Quota exceeded"
5.7.1Delivery refused by policy"Message rejected for policy reasons"
5.7.26Authentication failure (DMARC)"DMARC fail"
4.2.1Mailbox temporarily disabled"Try again later"
4.4.1No answer from host"Connection timed out"

Notice that 5.2.2 is technically permanent but reflects a transient situation: the mailbox is full right now. Best practice is to treat it as soft for the first 48-72 hours, then suppress.

How the Big Providers Actually Respond

The RFC is the theory. In practice each provider has its own dialect. Here are bounces you will recognise:

Gmail

550-5.7.1 [203.0.113.10  19] Our system has detected that this message is
550-5.7.1 likely unsolicited mail. To reduce the amount of spam sent to Gmail,
550 5.7.1 this message has been blocked.

Gmail loves the 5.7.1 code for reputation-based blocks. The IP in brackets is yours. If you see this repeatedly you have a reputation problem, not a content problem.

Outlook / Microsoft 365

550 5.7.606 Access denied, banned sending IP [203.0.113.10]

The 5.7.606-5.7.614 range refers to Microsoft IP block lists. Each suffix tells you which list. 5.7.606 is the most common: the connecting IP is in their general ban list. You will need to submit a delisting request at sender.office.com.

Italian providers (Aruba, Libero, TIM)

554 5.7.1 Service unavailable; Client host [203.0.113.10] blocked using SpamCop

Italian incumbents lean heavily on SpamCop, SORBS and Spamhaus. If you ship to a lot of @libero.it or @aruba.it addresses, monitor those three lists obsessively.

The Retry Strategy That Will Not Burn You

Retry policy is where most homemade senders fail. The rule is simple: respect the code, respect the receiver.

💡 Tip: Use exponential backoff with jitter. Never retry sooner than 5 minutes after the first attempt. Cap at 72 hours total.
def next_retry_delay(attempt):
    # attempt 1 = 5 min, 2 = 15 min, 3 = 1h, 4 = 4h, 5 = 16h
    base = 300  # 5 minutes
    delay = base * (4 ** (attempt - 1))
    jitter = random.uniform(0.8, 1.2)
    return min(delay * jitter, 86400)  # cap each step at 24h

And critically: do not retry the same recipient from a different IP hoping to "get lucky". Receivers correlate. You are just digging a deeper hole.

Bounce Handling Done Right

A production-grade bounce handler does five things, in order:

  1. Parses the SMTP reply into (class, enhanced, text).
  2. Maps to one of: hard, soft, reputation, policy.
  3. Updates the recipient state (active, suppressed, paused).
  4. Emits an event for your analytics so trends are visible.
  5. For reputation/policy failures, alerts on-call before retries pile up.

The fifth point is the one most teams skip. By the time you notice a Gmail block in your dashboard, you may already have queued ten thousand retries. A real-time alert on the first 5.7.1 saves your week.

The Suppression List Is Sacred

Once an address is suppressed, treat the suppression as a contract. Do not let support agents "re-enable" a hard-bounced address because the customer "says it works now". Force them to re-confirm with a double opt-in. The receiver remembers, and your IP reputation pays the bill.

⚠️ Warning: A single bad import that re-activates 10,000 hard-bounced addresses is the single most common cause of overnight blacklisting.

Closing the Loop

SMTP codes are a language. Once you read them fluently your queue behaves predictably, your reputation stops drifting, and on-call stops being woken up by deliverability incidents. The cheapest improvement most teams can make is not buying a dedicated IP or rewriting their templates: it is parsing bounces correctly.

If you would rather not build that logic yourself, Target SMTP classifies every bounce against the latest RFC 3463 codes, maintains per-receiver suppression policies, and exposes the parsed events through webhooks so your application reacts in seconds, not hours. The Send-Time Firewall will even block a send the moment a recipient enters the suppression list, preventing the second-bounce problem at the source.

Tag #smtp #bounce #deliverability #rfc3463

Related posts