← All posts

A Field Guide to SMTP Error Codes (4xx vs 5xx, and What to Do)

A
Admin
·

Your monitoring fires at 3 AM: "SMTP delivery failures spiking." You check the logs and see 550 5.1.1 User unknown, 421 Try again later, and 535 Authentication failed. Which ones do you retry? Which ones mean your config is broken? Which ones are permanent?

The Mental Model

SMTP response codes follow a simple pattern defined in RFC 5321:

  • 2xx — Success. The message was accepted.
  • 4xx — Temporary failure. Try again later — the problem might resolve itself.
  • 5xx — Permanent failure. Don't retry — the message will never be accepted.

That's the spec. In practice, real-world mail servers bend these rules constantly. Some servers return 4xx for permanent problems (to avoid giving spammers useful information). Some return 5xx for temporary issues (misconfigured servers). Treat the codes as guidelines, not gospel.

4xx Codes — Temporary Failures (Soft Bounces)

421 — Service Not Available

The server is temporarily unable to handle your connection. Common causes: server restarting, too many concurrent connections, rate limiting kicking in. Action: Retry with exponential backoff.

450 — Mailbox Unavailable

The recipient's mailbox exists but is temporarily unavailable — usually because it's locked by another process or the server is applying policy checks. Action: Retry after 5-15 minutes.

451 — Local Error in Processing

The receiver's server hit an internal error while processing your message. This is the server's problem, not yours. Action: Retry with backoff. If persistent, the recipient's server admin needs to fix it.

452 — Insufficient Storage

The recipient's mailbox is full, or the server is out of disk space. Action: Retry periodically (hours, not minutes). Consider alerting if this persists for the same recipient — their mailbox may be permanently full (abandoned account).

5xx Codes — Permanent Failures (Hard Bounces)

550 — Mailbox Not Found

The most common permanent error. The email address doesn't exist on that server. 550 5.1.1 The email account does not exist is Gmail's version. Action: Add to suppression list immediately. Do not retry. Continuing to send to non-existent addresses damages your sender reputation.

551 — User Not Local

The recipient's server knows the address but says the user has moved. Sometimes includes a forwarding address. Action: Update the recipient address if a forward is provided. Otherwise, suppress.

552 — Message Too Large

Your message exceeds the recipient server's size limit. Action: Reduce attachment sizes or host them externally. Don't retry without reducing the message size.

553 — Mailbox Name Invalid

The email address format is rejected — the local part contains characters the server doesn't accept. Action: Validate email addresses at signup. Suppress this address.

554 — Transaction Failed

A catch-all permanent error. Often used for policy rejections: "Your IP is blacklisted," "Message rejected due to content," "SPF check failed." Action: Read the full error text. It usually contains the specific reason.

Authentication Errors

535 — Authentication Failed

Your SMTP username or password is wrong, or the auth mechanism isn't supported. Action: Check your credentials immediately. This is a configuration error, not a recipient problem. Don't retry — every failed auth attempt may trigger account lockout.

530 — Authentication Required

The server requires authentication but you're trying to send without it. Action: Update your SMTP config to include credentials. This isn't a transient error.

Retry Strategy

Code ClassStrategyMax RetriesBackoff
421Retry51min, 5min, 15min, 1hr, 4hr
450, 451Retry35min, 30min, 2hr
452Retry (slow)31hr, 6hr, 24hr
550 (5.1.1)Suppress0
552Fix message0
535, 530Fix config0
554Investigate0

Debugging the SMTP Conversation

When error codes aren't enough, you need to see the full SMTP conversation — the sequence of commands and responses between your app and the receiving server.

Send your email through MailHog.site and inspect the full headers and SMTP session data. You'll see every EHLO, MAIL FROM, RCPT TO, and DATA exchange, making it clear exactly where the conversation fails.

FAQ

Should I retry on all 4xx errors?

Yes, with exponential backoff. But set a maximum retry count (3-5 attempts) and a maximum retry window (24-48 hours). If a 4xx persists beyond that, treat it as a permanent failure for operational purposes.

What does "5.7.1 Message rejected due to content" mean?

The receiving server's content filter flagged your message as spam or policy-violating. Check your email's spam score and review the content for triggers. Common causes: URL shorteners, ALL CAPS subjects, or sending from a domain without proper DKIM/SPF/DMARC authentication.

How do I build a suppression list?

Add any email address that returns a 550 (5.1.1) to a suppression list in your database. Before sending any email, check the suppression list first. Most email APIs (SendGrid, Postmark, SES) maintain their own suppression lists, but you should maintain your own too for the addresses you've collected directly.

← Back to all posts