How SMTP reply codes work

Every SMTP command gets a 3-digit response. Two important groupings:

2xx โ€” Positive responses

CodeMeaning
220Service ready (server's first message)
221Closing channel (after QUIT)
235Authentication successful
250OK โ€” most common success response
251User not local; will forward
252Cannot VRFY user but will accept message

3xx โ€” Intermediate (waiting)

CodeMeaning
334Continue authentication (server expects next AUTH chunk)
354Start mail input โ€” end with <CRLF>.<CRLF>

4xx โ€” Temporary failure (retry)

CodeMeaning
421Service not available, closing channel. Overloaded or shutting down.
450Mailbox temporarily unavailable. Try later.
451Local error in processing. Often greylisting or quota.
452Insufficient system storage. Mailbox or disk full.
454TLS not available / authentication failed temporarily

5xx โ€” Permanent failure (bounce)

CodeMeaning
500Syntax error, command unrecognized
501Syntax error in parameters or arguments
502Command not implemented
503Bad sequence of commands
530Authentication required (STARTTLS-only or AUTH-required server)
535Authentication credentials invalid
550Mailbox unavailable. Most common bounce โ€” user doesn't exist or rejected by policy.
551User not local; please try <forward-path>
552Mail action aborted: exceeded storage allocation
553Mailbox name not allowed
554Transaction failed โ€” "I don't like your message"

Enhanced Status Codes (RFC 3463) โ€” the dot codes

You'll often see replies like 550 5.1.1 The email account that you tried to reach does not exist. That 5.1.1 is an Enhanced Status Code, formatted class.subject.detail.

The common ones

CodeMeaning
5.1.1Bad destination mailbox address (user doesn't exist)
5.1.2Bad destination system address (domain doesn't exist)
5.1.8Bad sender's system address
5.2.1Mailbox disabled
5.2.2Mailbox full
5.4.1No answer from host
5.4.4Unable to route
5.7.1Delivery not authorized โ€” message rejected by policy (SPF/DKIM/DMARC fail, blacklist)
5.7.26Multiple authentication checks failed
4.4.1No answer from host (temp)
4.7.1Delivery temporarily blocked
If you're debugging bounces

The numerical reply code tells you success/failure category. The enhanced code tells you why. The text after is the human-readable explanation, varies by server. When troubleshooting deliverability, always look at all three โ€” the text often points to specific SPF/DKIM/DMARC issues or blocklist hits.

Common bounce reasons by code

BounceLikely cause
550 5.1.1Recipient address invalid โ€” typo, user left company
550 5.2.2Mailbox full
550 5.7.1 SPFYour IP isn't in the sender's SPF record
550 5.7.1 DMARCDMARC alignment failed (SPF and/or DKIM didn't align with From: domain)
550 5.7.1 listed at...Your sending IP is on a blacklist (Spamhaus, etc.)
421 4.7.0 Try again laterGreylisting โ€” server expects a retry. Will succeed in 5-30 min.
451 4.7.1 GreylistingSame as above, different format
550 5.7.26 Multi-auth failsGmail-style: SPF, DKIM, DMARC all failed; message rejected

Reading SMTP responses in real mail troubleshooting

When email fails, the SMTP response code is often the first clue to what went wrong. Every SMTP transaction is a series of commands and responses, and the responses are structured โ€” a three-digit code followed by text explaining the code. Reading these codes correctly can immediately tell you whether the problem is temporary (retry will succeed) or permanent (fix the sender before retrying).

The first digit of the response code tells you the general category. 2xx is success. 3xx is intermediate progress (continue with the next step). 4xx is a temporary failure (retry later). 5xx is a permanent failure (don't retry). The second and third digits narrow down the specific meaning within the category.

The 2xx codes: everything is fine

You'll see these in successful mail exchanges. 220 (service ready) at the start of an SMTP session. 250 (requested mail action OK, completed) after each command that worked. 251 (user not local, will forward). 354 (start mail input) is the response to DATA that tells you to start sending the message body.

If you see 2xx codes throughout a session but the recipient still doesn't get the mail, the delivery to the recipient's mailbox happened at the SMTP level โ€” the problem is somewhere downstream (spam filter, mailbox rules, quota, etc.).

The 4xx codes: try again later

The most useful 4xx codes:

421 Service not available

The receiving server is telling us to go away temporarily. Common causes: server maintenance, temporary overload, or the server being taken offline. Well-behaved sending servers will retry after a delay.

450 Requested mail action not taken: mailbox unavailable

Usually means the mailbox exists but the server can't deliver right now. Might be temporarily locked, might be full, might be under maintenance. Retry appropriate.

451 Requested action aborted: local error in processing

Some kind of transient server-side problem. Might be a temporary disk issue, might be a transient database problem, might be a message queue issue. Retry appropriate.

452 Requested action not taken: insufficient system storage

The server is out of disk space. Retry might work later after cleanup. Uncommon on modern well-managed servers.

454 TLS not available due to temporary reason

TLS negotiation failed on the receiving side. Might be certificate rotation in progress, might be transient. Retry appropriate.

The 5xx codes: permanent failure

Do not retry. Fix the underlying issue on the sending side before trying again. Common 5xx codes:

550 Requested action not taken: mailbox unavailable

The most common permanent failure. Usually means the mailbox doesn't exist. The message following the 550 often specifies why: "No such user here," "User unknown," "Mailbox not found."

Sometimes 550 also gets used for policy violations (mail rejected because of SPF failure, because the IP is on a blocklist, because content trips a spam rule). The explanatory text distinguishes.

551 User not local

The recipient isn't on this server. The response usually indicates where to send it instead.

552 Requested action aborted: exceeded storage allocation

The recipient's mailbox is full. The sending server can't deliver. The recipient needs to clean up before mail can be accepted.

553 Requested action not taken: mailbox name not allowed

The recipient address has invalid syntax, or contains characters the server rejects. Fix the address.

554 Transaction failed

The most common "we don't want this mail" rejection. Often used for spam-related rejections. The explanatory text usually specifies the reason: "SPF failed," "Message content rejected," "IP blocked."

Enhanced status codes provide the specifics

RFC 3463 defined a three-part enhanced status code format that adds structured meaning: X.X.X. The first digit matches the SMTP category (2, 4, or 5). The second identifies the subject class (addressing, mailbox, mail system, network, protocol, security, content). The third specifies the detail within the subject.

You'll often see both the SMTP code and the enhanced code together in responses. 550 5.1.1 User unknown. The 5.1.1 tells you specifically that this is a permanent addressing issue with the recipient. 550 5.7.1 Access denied tells you it's a security/policy denial rather than a mailbox issue.

Common enhanced codes worth memorizing

5.1.1 Bad destination mailbox address

The recipient doesn't exist. The address might be misspelled. Common in bounce messages when a sender misspells the recipient.

5.1.2 Bad destination system address

The recipient's domain doesn't exist or has no working mail server. Different from 5.1.1 โ€” the address itself is unroutable, not just unknown at the destination.

5.7.1 Delivery not authorized, message refused

Policy denial. Usually spam-related. The IP might be on a blocklist. The SPF check might have failed. The content might trip a filter rule.

5.7.7 Message integrity failure

DKIM verification failed. The signature doesn't match the message content. Either the message was modified in transit, or the signature was forged.

5.4.7 Delivery time expired

A queued message has been retrying for too long without success. Sending server is giving up. The original bounce reason should have been reported earlier.

What I actually do with these codes

Reading bounce messages

Every bounce message includes the SMTP response from the receiving server. Reading the code and text tells me exactly why the message failed. 5.1.1 with "User unknown" means the address is wrong. 5.7.1 with "SPF check failed" means the domain's SPF record doesn't include the sending IP. 5.7.7 with "DKIM signature failed" means the message was modified after signing.

Once I know the specific failure category, the fix is usually obvious.

Debugging queue backlogs

If a mail server has messages piling up in the queue, checking what SMTP responses are causing them to sit reveals the problem. A wave of 421s means the destination is unreachable temporarily. A wave of 550s means the recipient rejects the mail (usually a bad address pattern). A wave of 5.7.1s means we're being blocked, and I need to investigate why.

Testing delivery

Sending a test message and reading the raw SMTP transaction (via telnet or a modern equivalent) is the fastest way to verify that a mail path actually works. Every response is explicit โ€” no ambiguity about whether the message got through or not.

Related tools

For understanding why mail is landing in junk rather than being rejected outright, the Email Header Analyzer shows the delivery path and authentication results. For checking a domain's mail configuration (SPF, DKIM, DMARC, MX), the Email Health Check catches most common misconfigurations. For checking whether a sending IP is on any blocklists (which cause 5.7.1 rejections), the DNSBL Blacklist Check queries six major lists.