Fix

SMTP Errors and Retry Strategy

Interpret SMTP 4xx and 5xx responses, enhanced status codes, and retry behavior for transactional email.

Updated

TL;DR

Treat SMTP 4xx responses as temporary and 5xx responses as permanent unless provider documentation says otherwise. Retry temporary failures with backoff, never retry permanent failures blindly, and use webhooks for final post-acceptance delivery state.

What you will learn

  • Distinguish transient SMTP failures from permanent failures
  • Understand enhanced status codes
  • Avoid duplicate transactional email during retries

Basic SMTP response classes

ClassMeaningRetry behavior
2xxAccepted or successful commandContinue
4xxTemporary failureRetry with backoff
5xxPermanent failureDo not retry without a change

The first digit is the most important operational signal. Enhanced status codes add detail, such as 4.2.2 for mailbox full or 5.1.1 for a bad address.

Common temporary failures

Temporary responses usually mean the sender should try again later:

  1. 421 service not available.
  2. 450 mailbox unavailable.
  3. 451 local processing error.
  4. 452 insufficient storage.
  5. 4.7.x throttling, reputation, or policy deferral.

Use exponential backoff with jitter. Avoid retry storms. A good pattern is retrying after seconds, then minutes, then longer intervals, with a maximum retry window appropriate to the message type.

Common permanent failures

Permanent responses usually mean a retry will not help:

  1. 550 mailbox unavailable or policy rejection.
  2. 551 user not local.
  3. 552 exceeded storage allocation.
  4. 553 mailbox name not allowed.
  5. 554 transaction failed.

Permanent recipient failures should feed the suppression list. Re-sending to a known bad address hurts reputation and creates noisy analytics.

App retry rules

When submitting to Postscale by SMTP:

  1. Retry network timeouts cautiously.
  2. Retry 4xx SMTP responses with backoff.
  3. Do not retry 5xx responses unless you corrected the cause.
  4. Do not generate a new password reset token for every retry.
  5. Keep a message idempotency key or application event id.

When sending by REST, apply the same principle: retry transport errors and 5xx API errors carefully, but fix validation errors instead of retrying them.

Accepted is not delivered

SMTP acceptance means the provider took responsibility for the message. It does not mean Gmail, Outlook, Yahoo, or another mailbox accepted the message.

Your application should store states such as:

  1. queued
  2. accepted
  3. delivered
  4. deferred
  5. bounced
  6. complained

Use webhook retries and idempotency to update final state reliably.

Troubleshooting checklist

  1. Confirm the From domain is verified.
  2. Confirm the SMTP port and TLS mode match.
  3. Check whether the recipient is suppressed.
  4. Inspect the enhanced status code.
  5. Compare failures by mailbox provider.
  6. Look for a recent template or list-quality change.
  7. Review SPF, DKIM, and DMARC alignment.

References

Frequently asked questions

Should I retry SMTP 421?
Yes. 421 is generally a temporary service-unavailable response. Retry with backoff unless your provider gives a more specific instruction.
Does SMTP accepted mean delivered?
No. Accepted means the provider accepted responsibility for delivery. Use delivery, bounce, defer, and complaint webhooks for final state.

Related guides

Put the guide into production

Postscale brings sending, inbound processing, DMARC reporting, and masked addresses behind one API so the operational pieces stay connected.