SMTP Error Codes: Enhanced Status Codes and Retry Decisions

· Published · 12 min read

SMTP replies split into success, transient retry and permanent-failure handling while enhanced status subject families and diagnostic evidence guide operations

An SMTP code is an instruction about one command or delivery attempt, not a complete diagnosis. The first digit provides the broad action: success, transient failure or permanent failure. Enhanced status codes and the full remote text add context. Operators need all three, plus the command, MX, time and queue history, before automating a response.

Read SMTP reply classes and enhanced status codes

RFC 5321 defines SMTP reply classes. A 2xx reply is positive completion for the command. A 4xx reply is transient negative completion, so the client normally queues and retries within its configured lifetime. A 5xx reply is permanent negative completion; retrying the same unchanged recipient and message is not expected to succeed.

Enhanced status codes use X.Y.Z. The class repeats success, temporary or permanent meaning. The subject identifies address, mailbox, mail system, network or routing, delivery protocol, content or media, or security and policy. The detail refines that subject. RFC 5248 maintains the registry, while providers may add explanatory text and operational links.

Why the complete reply and SMTP command matter

Parsing only the visible three-digit reply loses important evidence. Treating every 4xx as a reason to retry aggressively can amplify rate limiting; treating every 5xx as an invalid address can wrongly suppress a valid recipient after a content or policy rejection. The action depends on reply class, enhanced subject, command and provider context.

Provider text can change, and one numeric code can accompany different policies. Preserve the full response and version parsers conservatively. Use known structured codes for automation, but route unknown combinations for observation rather than guessing a permanent recipient state. Store the parser decision beside the original reply so later rule changes can be audited and historical incidents can be reclassified without losing source evidence.

Classify SMTP responses and choose safe queue actions

  1. Capture the complete attempt. Log UTC timestamp, remote MX and IP, local IP, TLS state, SMTP command, basic reply, enhanced code, full text, queue ID and attempt.
  2. Classify the reply. Use the first digit for immediate queue behavior, then use the enhanced subject and text for diagnostic routing.
  3. Handle success correctly. Record the accepted recipient and continue the SMTP transaction. Acceptance proves handoff, not inbox placement.
  4. Handle transient failure. Keep the message queued, honor retry-after guidance if present, apply bounded backoff and avoid opening excessive connections.
  5. Handle permanent failure. Stop unchanged retries for that recipient. Decide whether to suppress the address, correct authentication, change content or escalate policy.
  6. Aggregate patterns. Group by receiving organization or MX, reply signature, IP, domain, stream, cohort and deployment so incidents emerge from individual attempts.
  7. Protect retry budgets. Set maximum queue age and attempt controls by message purpose. Expired time-sensitive mail should fail visibly rather than arrive uselessly late.
  8. Verify remediation. Test a representative message, observe the new remote reply and confirm queues drain without complaint or volume spikes.

Map SMTP evidence to retry, suppression or repair

Reply evidenceQueue actionInvestigation
2xx after final contentMark recipient acceptedContinue delivery accounting; do not label inbox
4xx mailbox or system conditionQueue and retry with controlWatch duration and provider-wide distribution
4xx security or policy conditionSlow and investigateReview authentication, reputation, rate and full text
5xx address failureStop and suppress address when definitiveProtect against repeated invalid-recipient attempts
5xx content or policy failureStop unchanged retryCorrect the causal message or policy issue before resubmission

Worked incident: provider policy deferrals build a queue

A sender sees a growing queue for one receiving network. Replies are 4xx policy deferrals, not connection failures. The surge began after a volume increase from a less-engaged cohort. Opening more connections would worsen the signal.

The MTA reduces the affected stream’s rate, keeps messages within their useful queue lifetime and preserves every full reply. Operations pauses the new cohort and verifies authentication and complaint data. As deferrals decline, capacity rises gradually. Permanent address failures discovered elsewhere follow the separate suppression path and are never retried as though they were temporary.

SMTP attempt and queue evidence to retain

  • Attempt: queue ID, message ID, recipient hash or protected identifier, attempt count, time and message age.
  • Connection: receiving domain, MX, remote IP, local IP, TLS result, connection count and session timing.
  • Reply: command, three-digit code, enhanced status code, full text and provider reference URL.
  • Context: stream, campaign, tenant, DKIM and From domain, sending IP, cohort and recent change.
  • Outcome: later acceptance, permanent failure, queue expiry, suppression, corrected retry or incident linkage.

SMTP parsing and retry mistakes that cause harm

  • Retrying 5xx unchanged: this wastes capacity and can look abusive.
  • Suppressing every 5xx address: content, authentication and policy failures do not prove the mailbox is invalid.
  • Ignoring the SMTP command: a reply to RCPT TO differs operationally from one returned after message content.
  • Discarding full text: enhanced detail and provider remediation instructions may be present only there.
  • Using endless retries: queue lifetime must match message value and generate a visible terminal outcome.

SMTP response troubleshooting checklist

  • Log the full reply, command, MX, IP, time and queue ID.
  • Parse both basic and enhanced codes conservatively.
  • Treat 2xx as acceptance, not proof of inbox placement.
  • Back off and bound retries for 4xx responses.
  • Stop unchanged recipient retries after definitive 5xx failure.
  • Separate address, content, system and policy actions.
  • Aggregate patterns by provider, stream and recent change.
  • Retest the repaired path and verify queue recovery.

Read the basic reply, enhanced code and text together

550 5.1.1 Recipient address rejected: user unknown
|   |     |
|   |     +-- remote explanatory text
|   +-------- enhanced status: class.subject.detail
+------------ basic SMTP reply

The reply also belongs to an SMTP command. A 550 after RCPT TO can reject one recipient before message content is transferred. A 550 after the final dot can reject the completed message for content or policy. Store the command stage with the reply.

Use enhanced status subject families for routing

SubjectFamilyTypical investigation
X.0.XOther or undefinedUse full text and provider documentation
X.1.XAddressingRecipient, sender or destination syntax/existence
X.2.XMailboxDisabled, full, inactive or recipient policy
X.3.XMail systemReceiver capacity, configuration or message size
X.4.XNetwork and routingDNS, connection, timeout or routing loop
X.5.XDelivery protocolUnsupported command or protocol state
X.6.XContent or mediaEncoding, conversion, content or media capability
X.7.XSecurity or policyAuthentication, reputation, rate, content policy or authorization

The first digit still controls the broad queue action: 4 is temporary and 5 is permanent for that attempt. The subject does not turn every 5.7.X into an invalid recipient.

Interpret common enhanced status codes conservatively

CodeCommon meaningSafe sender action
2.0.0SuccessRecord acceptance for the completed command
2.1.5Destination address validContinue transaction; not proof of final inbox placement
4.2.0Other temporary mailbox conditionQueue with bounded retry and inspect duration
4.2.2Mailbox fullRetry within policy; expire visibly when queue lifetime ends
4.3.0Temporary mail-system conditionCorrelate receiver-wide pattern and back off
4.4.1No answer from hostCheck DNS/network and normal retry path
4.4.2Bad connectionRetry with connection controls and inspect TLS/network
4.7.0Temporary security/policy conditionSlow down and investigate full provider text
5.1.1Bad destination mailbox addressStop unchanged retry and suppress when definitive
5.1.2Bad destination system addressVerify domain/routing; do not classify solely as user unknown
5.2.1Mailbox disabledStop delivery and apply address-state policy
5.2.2Mailbox full as permanent responseStop unchanged retry; retain exact provider text
5.3.4Message too bigCorrect message size before resubmission
5.6.1Media not supportedCorrect MIME/content representation
5.7.1Delivery not authorized or refusedInvestigate policy, authentication, reputation and full text

Providers can return additional registered or provider-specific detail and URLs. Maintain provider parsers as versioned hints, while the raw reply remains the source evidence.

Interpret the same class differently by SMTP stage

StageWhat a failure may indicateEvidence
ConnectNetwork, listener, reputation block or concurrency pressureRemote IP, timeout/refusal, TLS and connection rate
EHLO/HELOProtocol, hostname or receiver policyPresented name and advertised capabilities
MAIL FROMEnvelope sender, authentication or sender policyReturn path, SPF identity and full reply
RCPT TORecipient state, relay authorization or recipient policyProtected recipient identifier and per-recipient reply
DATA commandReceiver not ready to accept contentSession history and size declaration
End of DATAMessage content, authentication, reputation or policyMessage ID, DKIM/From, content and full final response

Inspect Postfix and Exim queues before changing them

# Postfix: list queue, JSON output where supported, inspect one message
postqueue -p
postqueue -j
postcat -q QUEUE_ID

# Exim: list queue and inspect headers, body and log for one message
exim -bp
exim -Mvh MESSAGE_ID
exim -Mvb MESSAGE_ID
exim -Mvl MESSAGE_ID

Run inspection commands with appropriate privileges and protect message content. Queue bodies can contain personal or confidential data.

Unsafe/destructive commands: postsuper -d QUEUE_ID and exim -Mrm MESSAGE_ID remove queued mail. Use an exact validated ID, capture evidence first and obtain operational approval. Never replace the ID with an unresolved variable or broad queue selection. Deletion does not correct the source that generated the mail.

Use bounded provider-aware retries

Temporary failures need delayed retry, not immediate repeated connections. Use increasing intervals with jitter, provider-specific concurrency and rate controls, and a maximum queue age appropriate to message purpose. A password reset that arrives after two days may be useless; a nonurgent statement may tolerate a longer window.

PatternAdjustment
Connection-level 4xx across a receiverReduce concurrency and connection creation
Policy 4xx after volume spikeReduce recipient rate and investigate audience/reputation
One mailbox temporarily fullRetry that recipient without slowing unrelated providers
Message-specific temporary content responseHold affected message class and inspect before mass retry
Queue nearing useful lifetimeExpire visibly and notify the owning application

Do not reset retry counters by repeatedly reinjecting the same unchanged message.

Separate synchronous SMTP replies from later DSNs

An SMTP server can accept a message and later generate a Delivery Status Notification when downstream delivery fails. Parse the DSN fields and original recipient information safely; do not treat the human-readable attachment as the only evidence.

EvidenceMeaning
Final-RecipientRecipient identity for the reported delivery action
ActionFailed, delayed, delivered, relayed or expanded
StatusEnhanced status associated with the DSN outcome
Diagnostic-CodeRemote or gateway diagnostic detail
Will-Retry-UntilDeclared retry horizon when provided for delay

Authenticate and validate incoming bounce sources where possible, correlate with the original envelope/message ID, and prevent forged DSNs from suppressing unrelated recipients.

Version the SMTP parser and preserve unknown replies

if basic_class == 2:
    action = "accepted_for_this_command"
elif basic_class == 4:
    action = "queue_with_bounded_backoff"
elif basic_class == 5:
    action = classify_permanent(enhanced_code, command, full_text)
else:
    action = "manual_or_protocol_review"

This pseudocode intentionally avoids suppressing every 5xx recipient. A definitive 5.1.1 at RCPT can drive address suppression; a 5.7.1 after DATA requires policy/authentication/content investigation. Store parser version, selected action and raw reply so old incidents can be reclassified when provider behavior changes.

Parse the complete SMTP reply before assigning a cause

451 4.7.0 Temporary server error. Please try again later.
|   |     |
|   |     provider text and possible support reference
|   enhanced status code
basic three-digit reply

The first digit separates positive, temporary negative and permanent negative completion. Enhanced status codes add class, subject and detail, but provider text supplies operational context and can change. Preserve the remote hostname, command stage, complete multiline reply, queue ID, recipient domain, sending IP and UTC time. A dashboard label such as “blocked” discards evidence.

Do not parse human text alone. Normalize known codes while keeping raw replies so new or changed responses remain diagnosable.

Interpret the command stage and recipient scope

StageExample boundaryOperational meaning
Connect/bannerNetwork, rate or service availabilityNo message transaction began
EHLO/STARTTLSProtocol or transport policyCheck capability, certificate and MTA-STS/DANE context
MAIL FROMSender identity or session policyMay affect all recipients in transaction
RCPT TORecipient validity or sender policyClassify per recipient
After DATAMessage/content/authentication policyReceiver assessed submitted message
Later DSNDownstream failure after acceptanceCorrelate original recipient and status fields

The same numeric reply at another stage can require a different response.

Retry temporary failures without creating a traffic attack

next_delay = min(max_delay,
                 base_delay * 2^attempt + random_jitter)

queue key: receiver organization + route + reply class
stop: permanent recipient failure or queue lifetime expiry

Use the MTA’s standards-compliant scheduler and provider feedback. Do not immediately retry every 4xx recipient or open more connections to compensate; synchronized retries amplify receiver pressure. Separate queues by receiving organization, cap concurrency, reuse connections responsibly and preserve oldest-message age.

A 5xx is normally permanent for that transaction or recipient, but policy can change after remediation. Do not repeatedly resend the same rejected campaign automatically. Correct authentication, permission or content first and create a controlled new attempt only when justified.

Map error families to accountable investigations

FamilyFirst evidenceDo not do
Unknown userRecipient source, first-seen and prior deliveryRetry permanently invalid addresses
Authentication/policyReceived artifact, SPF/DKIM/DMARC and provider requirementChange IP before fixing identity
Rate/reputation deferralProvider-hour volume, complaints, replies and queuesIncrease concurrency blindly
Content/malwareExact MIME, URLs, attachment and security releaseRandomly rewrite until accepted
Mailbox full/resourceEnhanced code, duration and recipient historySuppress immediately without policy

Maintain provider-specific parsers as versioned mappings, but route unknown replies to review. Official support pages are more reliable than copied code lists.

Handle delivery status notifications and multiline replies without losing recipients

An SMTP transaction can produce one reply for a connection, one for each RCPT command and another after DATA. A message with ten recipients can have some accepted and some rejected before content submission. Store disposition per recipient and a transaction-level result. Do not label the whole message delivered because one recipient returned 250.

550-5.7.1 First explanatory line
550-5.7.1 Additional policy context
550 5.7.1 Final line with support reference

Final-Recipient: rfc822; [email protected]
Action: failed
Status: 5.1.1
Diagnostic-Code: smtp; 550 5.1.1 recipient does not exist

Multiline replies repeat the code with a hyphen until the final line uses a space. Preserve every line. A later DSN is a structured MIME report and can describe delayed, failed or delivered status after another server accepted the message. Parse its per-recipient fields and correlate Original-Envelope-ID, Final-Recipient, Action, Status and Diagnostic-Code where present.

ClassQueue actionAudience action
2.x.x successComplete that SMTP responsibility boundaryNo engagement inference
4.x.x temporaryRetry under bounded scheduleDo not suppress merely from one transient reply
5.1.1 invalid recipientStop retrying recipientDurably suppress invalid address
5.7.x policy/securityStop transaction as directedInvestigate identity/reputation; do not call address invalid

Provider-specific codes sometimes embed remediation URLs or identifiers. Sanitize them for dashboards but keep the raw value under access control. Group variants into a normalized family only after exact parsing tests, and measure the unknown family so parser drift cannot disappear.

When a receiver changes wording, update mappings prospectively and replay a governed sample. Do not rewrite historical categories without recording the classifier version.

Turn normalized replies into safe queue controls

Define actions at provider and reply-family level: normal scheduling, reduced concurrency, longer backoff, route hold, recipient suppression or security escalation. Automatic rules need minimum volume, expiry and an owner. A temporary reputation deferral should slow the relevant receiver queue; it should not block unrelated networks or convert recipients to hard bounces.

Monitor attempted recipients, unique recipients, reply events, oldest queue age, retry attempts and final outcomes. Event count can grow during retries even when recipient count does not, so use both. Alert on a rising share of unknown replies because provider wording or parser behavior may have changed.

When an incident ends, let the queue recover under controlled throughput. Releasing every deferred message at once can recreate the condition. Prefer oldest appropriate wanted mail, respect message expiry and suppress recipients whose status became permanent meanwhile. Keep a sample of final replies after recovery to prove the receiving boundary normalized.

Test the reply parser against real and adversarial fixtures

Maintain sanitized fixtures for multiline replies, missing enhanced codes, IPv6 addresses, Unicode text, provider URLs, commas, line wrapping and DSNs with several recipients. Assert the raw value remains intact, normalized family is correct and no address or token leaks into broad dashboards.

Unknown input must produce an unknown classification, not success. Version mappings, measure classification coverage and require review before an automated action becomes more destructive, such as suppression or route shutdown.

Escalate with a compact reproducible case

Provide the receiving organization, affected IP/domain, UTC window, representative full replies, queue behavior, authentication evidence, recent changes and corrective actions. Use anonymized recipient examples requested by the provider. A support ticket should demonstrate that the sender has stopped harmful traffic and can reproduce the failure; it should not ask the receiver to override unresolved permission or security problems.

Primary references

Continue learning

Related technical notes

Technical review

Need this checked against your own sending system?

Share the domain, headers, bounces, provider warning, logs, or infrastructure symptom and NitWings will identify the practical next step.

Schedule a Technical Review
Advertisement