BookMySpot

Deliverability

SMTP Bounce Codes Explained: 4xx and 5xx Reply Codes

SMTP bounce codes are the numeric replies a receiving mail server sends when it can’t or won’t accept a message. Codes starting with 4 (like 421 or 452) are temporary failures, so the sender should retry later. Codes starting with 5 (like 550 or 554) are permanent failures, so retrying the same message won’t work. Most bounces also carry an enhanced status code such as 5.1.1, which tells you why: a bad address, a full mailbox, a policy block, and so on.

This guide explains how to read both kinds of codes and gives a reference table of real errors from Gmail, Microsoft, and Yahoo, with what each one means for your list.

The two codes in every bounce

A typical bounce line looks like this:

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

It contains three parts:

  1. 550: the basic SMTP reply code, defined in RFC 5321.
  2. 5.1.1: the enhanced status code, defined in RFC 3463.
  3. The text: a human-readable explanation, which each provider writes however it likes.

The basic code tells your mail server what to do next (retry or give up). The enhanced code and the text tell you what went wrong. The M3AAWG Sender Best Common Practices make the point that the numeric codes weren’t designed for bulk senders and don’t say whether an address should be removed from a list. You need the descriptive text for that.

Basic SMTP reply codes (RFC 5321)

The first digit sets the outcome:

First digitMeaningWhat your server does
2xxSuccessMessage accepted
3xxIntermediateWaiting for more input (for example 354 after DATA)
4xxTransient failureQueue the message and retry later
5xxPermanent failureDon’t repeat the same request

The codes you’ll see most in bounces, with their RFC 5321 meanings:

CodeRFC 5321 meaningIn practice
421Service not available, closing transmission channelServer busy, rate-limited, or shutting down. Retry.
450Mailbox unavailable (for example busy or temporarily blocked)Temporary. Often rate limiting or greylisting.
451Action aborted: local error in processingTemporary server-side problem. Retry.
452Insufficient system storageTemporary. Often “mailbox full” or too many recipients.
550Mailbox unavailable (not found, no access, or rejected for policy)Permanent. Could be a bad address or a block. Read the enhanced code.
551User not local; please try another pathPermanent. Rare in modern mail.
552Exceeded storage allocationUsually permanent, but see the exception below.
553Mailbox name not allowed (for example bad syntax)Permanent. Malformed address or domain.
554Transaction failedPermanent. A catch-all for rejection.

The 552 exception: RFC 5321 section 4.5.3.1.10 notes that some servers return 552 when a message has too many recipients, where 452 is the correct code, and says clients should treat 552 in that situation as temporary.

Enhanced status codes (RFC 3463)

Enhanced codes have the form class.subject.detail.

The class repeats the outcome: 2 success, 4 persistent transient failure, 5 permanent failure.

The subject tells you which part of the system failed:

SubjectAreaWhat it usually points to
x.0.xOther or undefinedNo detail available
x.1.xAddressingThe address or domain is wrong
x.2.xMailboxThe recipient’s mailbox (full, disabled)
x.3.xMail systemThe receiving system
x.4.xNetwork and routingDNS, routing, timeouts
x.5.xMail delivery protocolSMTP protocol errors
x.6.xMessage content or mediaEncoding or media type
x.7.xSecurity or policyAuthentication, spam filtering, blocklists

Some specific detail codes from RFC 3463 worth memorizing:

  • x.1.1 Bad destination mailbox address (the part before the @ is invalid)
  • x.1.2 Bad destination system address (the domain is invalid)
  • x.2.1 Mailbox disabled, not accepting messages
  • x.2.2 Mailbox full (defined as a persistent transient failure)
  • x.2.3 Message length exceeds administrative limit
  • x.4.4 Unable to route
  • x.4.7 Delivery time expired
  • x.7.1 Delivery not authorized, message refused

The full registry is maintained by IANA under the SMTP Enhanced Status Codes page, which includes later additions such as x.1.10 for a recipient domain with a null MX (RFC 7505).

Common bounce codes by provider

Each mailbox provider writes its own text, so the same enhanced code reads differently in Gmail, Microsoft 365, and Yahoo. Here are the ones you’ll run into most.

Gmail SMTP error codes

From Google’s SMTP error reference:

CodeGmail’s text (abridged)TypeWhat to do
550 5.1.1The email account that you tried to reach does not existHardSuppress the address
553 5.1.2We weren’t able to find the recipient domainHardSuppress; check for a typo
550 5.2.1The email account that you tried to reach is inactiveHardSuppress
452 4.2.2The recipient’s inbox is out of storage spaceSoftRetry; watch for repeats
552 5.2.2The recipient’s inbox is out of storage space and inactiveHard in practiceSuppress
450 4.2.1The user you are trying to contact is receiving email too quicklySoftSlow down, retry later
421 4.7.0Try again later, closing connection (several variants)SoftRetry; check reputation if persistent
421 4.7.28Gmail has detected an unusual rate of emailSoftReduce volume
550 5.7.1This message is likely unsolicited email (one of several variants)BlockFix content, list quality, reputation
550 5.7.25Sending IP address doesn’t have a PTR recordBlockAdd reverse DNS
550 5.7.26Unauthenticated email is not accepted due to domain’s DMARC policyBlockFix SPF/DKIM alignment
452 4.5.3Your message has too many recipientsSoftSplit the recipient list

Microsoft 365 and Exchange Online

From Microsoft’s NDR reference for Exchange Online:

CodeMicrosoft’s descriptionTypeWhat to do
5.1.1Bad destination mailbox addressHardCheck the address; suppress if confirmed
5.1.10Recipient not found (SMTP address lookup failed)HardSuppress
5.4.1Recipient address rejected: Access deniedHardUsually the address doesn’t exist
5.4.1Relay Access DeniedConfigReceiving server or DNS misconfigured
5.7.1Delivery not authorizedBlockRecipient restricts senders (often a group)
4.4.7Message expiredSoft that gave upCheck the address and the receiving server

Note that Microsoft’s 5.2.2 means submission quota exceeded, a sender-side rate limit, not “mailbox full.” The same enhanced code can mean different things at different providers, which is another reason to read the text.

Yahoo

Yahoo’s SMTP error codes page groups errors by category rather than listing every code:

  • 554 “This user doesn’t have a yahoo.com account”: the address doesn’t exist. Yahoo says not to retry and to remove it from your list.
  • 421 / 451 temporary errors: unusual traffic, complaints, or busy servers. Retry later and review Yahoo’s sender requirements.
  • 553 / 554 permanent errors: invalid addresses, DMARC or DKIM failure, unacceptable content, or a Spamhaus listing. Don’t retry; remove addresses that produce 5xx errors.
  • “Excessive unknown recipients”: your server is sending to many invalid addresses. Yahoo tells senders to remove bouncing addresses.

How to act on a bounce code

Here’s a simplified decision function. It’s deliberately conservative: it only suppresses on clear addressing or mailbox failures and treats policy blocks as a sender problem.

import re

def classify_bounce(smtp_reply: str) -> str:
    """Return 'suppress', 'retry', 'fix_sender', or 'review'."""
    m = re.search(r'\b([245])\.(\d{1,3})\.(\d{1,3})\b', smtp_reply)
    basic = smtp_reply.strip()[:1]

    if not m:
        # No enhanced code: fall back to the basic reply class
        return 'retry' if basic == '4' else 'review'

    cls, subject, detail = m.group(1), m.group(2), m.group(3)

    if cls == '4':
        return 'retry'                       # mailbox full, throttling, greylisting
    if subject == '1' and detail in ('1', '2', '10'):
        return 'suppress'                    # bad mailbox, bad domain, null MX
    if subject == '2' and detail in ('1', '2'):
        return 'suppress'                    # disabled or full-and-inactive
    if subject == '7':
        return 'fix_sender'                  # auth, reputation, policy
    return 'review'                          # everything else: a human should look

print(classify_bounce("550 5.1.1 The email account that you tried to reach does not exist."))
# suppress
print(classify_bounce("550 5.7.26 Unauthenticated email from example.com is not accepted"))
# fix_sender

In production you’d also count repeated 4xx failures per address and suppress after a threshold. Our existing guide on bounce classification covers that policy side, and retry schedules covers how long to keep retrying a 4xx. If your ESP sends bounces as webhooks, see processing bounce webhooks.

Codes that confuse people

550 doesn’t always mean “user unknown.” RFC 5321 lets 550 cover a missing mailbox, lack of access, or a policy rejection. Always check the enhanced code. For the most common one, see 550 5.1.1 User Unknown.

5.2.2 isn’t always “mailbox full.” As noted above, Microsoft uses it for a sender submission quota.

“Mailbox full” can be a hard or a soft bounce. Gmail uses 452 4.2.2 for a full mailbox and 552 5.2.2 for one that’s full and inactive. More on this in “Mailbox Full” Bounces: Should You Remove the Address?

4.4.7 is a soft bounce that gave up. The sending system retried until the message expired. Look at the earlier deferral reasons to find the real cause.

5.7.x is about you. Policy codes are permanent for that message, but the recipient address is usually fine. Fix your authentication or reputation instead of deleting the contact. For the full breakdown, read Hard Bounce vs Soft Bounce: Causes and Fixes.

Prevent the codes you can control

You can’t prevent 4xx throttling at a busy provider, but you can prevent most 5.1.x errors before you send. The free email verifier on this site checks syntax, confirms the domain exists and has MX records, flags disposable and role-based addresses, identifies free-provider domains, and suggests fixes for common domain typos. That covers the causes of 553 5.1.2 and many typo-driven 5.1.1 errors. It doesn’t connect to the recipient’s mailbox, so it can’t tell you whether a specific user exists at a valid domain.

FAQ

What’s the difference between a 4xx and a 5xx SMTP code?

A 4xx code is a temporary failure, so your server should retry the message later. A 5xx code is a permanent failure for that message, and retrying it unchanged won’t succeed. Whether you should also remove the address depends on the enhanced code: 5.1.x usually means remove, 5.7.x usually means fix your sending setup.

What does SMTP error 554 mean?

RFC 5321 defines 554 as “Transaction failed,” a general permanent rejection. Providers use it for many reasons: Yahoo uses it for addresses that don’t exist and for policy rejections. Read the enhanced code and the text to see which one you have.

Where do I find the bounce code for a failed email?

If you send from an ESP, it appears in the bounce report or webhook event, usually in a field like diagnosticCode or reason. If you send from a regular mailbox, open the “Undeliverable” or “Delivery Status Notification” email and look for the line starting with a three-digit code, or the Diagnostic-Code field in the attached delivery report.

Are enhanced status codes the same at every provider?

The structure is standardized by RFC 3463, but providers apply the codes differently and write their own explanatory text. Microsoft’s 5.2.2, for example, means a sending quota was exceeded, while Gmail’s 552 5.2.2 means the recipient’s mailbox is full and inactive.

Check your list before you send

Free email verifier: syntax, MX, disposable and role-based addresses, typos. Paste up to 100 at once.

Verify emails free