SMTP Retry Queues: How Long Email Keeps Trying After a 4xx
SMTP senders should queue a message after a temporary failure and try again later. RFC 5321 says a retry interval should generally be at least 30 minutes and the give-up time generally needs to be at least four to five days, but it does not define one universal schedule. Your mail server controls the actual backoff and expiry policy.
A permanent 5xx reply follows a different path. It ends delivery for that recipient instead of entering the retry loop. A 2xx reply ends the sender's queue because the next SMTP server has accepted responsibility for the message, as RFC 5321 explains for a final acceptance reply.
One message becomes three recipient states
The useful unit is not the message alone. It is the message-recipient pair. One multi-recipient message can be accepted for one address, deferred for another, and rejected permanently for a third.
Here is a hypothetical queue trace. The times are from an illustrative policy, not a schedule required by SMTP:
2026-10-16 09:00 PKT queue Q7A9 created
alex@example.net
RCPT TO -> 250 2.1.5 Recipient OK
state -> handed_off
sam@example.org
RCPT TO -> 450 4.2.0 Mailbox temporarily unavailable
state -> queued
retry -> 09:30 PKT
lee@example.com
RCPT TO -> 550 5.1.1 User unknown
state -> failed
2026-10-16 09:30 PKT retry sam@example.org
RCPT TO -> 451 4.3.0 Temporary system problem
state -> queued
retry -> 10:30 PKT
2026-10-16 10:30 PKT retry sam@example.org
DATA final reply -> 250 2.0.0 Queued
state -> handed_off
The first delivery attempt produced three outcomes. Retrying the whole message as one blob would risk resending to Alex and ignoring Lee's permanent failure. The queue should retain the envelope and message data, while each recipient keeps its own status, attempt count, next-attempt time, and last diagnostic.
Which failures belong in the retry queue?
A 4xx SMTP reply is temporary. So are many connection, timeout, and DNS failures where the sender cannot yet make a permanent delivery decision. RFC 5321 section 4.5.4.1 requires mail that cannot be transmitted immediately to be queued and periodically retried.
The reply stage still matters. A 421 can close the service before or during a transaction. A 450 at RCPT TO defers one recipient. A 451 after the message body means the receiving server did not accept responsibility for that transaction. Preserve the command, three-digit reply, enhanced status code, and text instead of flattening them into retry: true.
A 5xx reply is a permanent failure for that attempt and recipient. The existing 550 5.1.1 guide owns the narrower invalid-recipient case. The hard-bounce and soft-bounce guide explains how later delivery evidence should affect address state.
Try usable MX hosts and their addresses as part of the delivery attempt before you decide the destination is temporarily unreachable. RFC 5321 section 5.1 requires SMTP clients to try relevant alternatives in order and says they should try at least two addresses when available. This is failover inside an attempt. Queue backoff begins when the available route still does not produce a final outcome.
Why is there no universal SMTP retry schedule?
The standard supplies boundaries, not a minute-by-minute calendar. It says the sender must delay another attempt to a failed destination, the interval should generally be at least 30 minutes, the give-up time generally needs to be at least four to five days, and the algorithm parameters must be configurable.
That wording leaves room for the failure reason and local workload. A sender may spread retries over time, cap the delay, or group work by destination so an unavailable domain is not hammered by thousands of queued messages. The receiving system cannot assume the next attempt will arrive at an exact time.
This is why a greylisting rule must tolerate a range. Greylisting intentionally returns a temporary reply and waits for a later attempt, but not every 451 is greylisting. Congestion, maintenance, routing failures, and local policy can produce similar evidence.
Do not confuse queue backoff with SMTP command timeouts. A client may wait several minutes for one server reply during an active session. Backoff is the delay before opening a later delivery attempt after the session or transaction has failed.
What should happen when the queue expires?
Expiry changes a temporary condition into a final outcome for this message. It does not rewrite the last 4xx into proof that the mailbox is invalid. RFC 3463 describes a 4.x.x status as a persistent transient failure: the message is valid, but a temporary condition caused delay or abandonment.
When the sender gives up, it should generate a non-delivery report to the envelope sender unless the message already has a null reverse-path. That null path prevents error messages from generating more error messages.
A delayed delivery status notification may include Will-Retry-Until. RFC 3464 section 2.3.9 defines it as the time after which the reporting MTA expects to abandon delivery attempts. The field is optional, and RFC 3461 does not require an MTA to send a delay notification at all. Silence therefore does not prove delivery, failure, or an empty queue.
Model the queue as recipient-scoped state
I would keep the scheduling policy explicit and testable. This small JavaScript function shows the boundary. Its 30-minute to six-hour backoff is one illustrative local policy. The five-day expiry follows the conservative end of the RFC's general guidance, but neither sequence is universal.
const delays = [30 * MINUTE, HOUR, 2 * HOUR, 4 * HOUR, 6 * HOUR];
const giveUpAfter = 5 * DAY;
function planRecipient({ replyCode, attempts, firstAttemptAt, now }) {
const replyClass = Math.floor(replyCode / 100);
if (replyClass === 2) return { state: "handed_off" };
if (replyClass === 5) return { state: "failed" };
if (replyClass === 4) {
if (now - firstAttemptAt >= giveUpAfter) {
return { state: "expired" };
}
const delay = delays[Math.min(attempts, delays.length - 1)];
return { state: "queued", nextAttemptAt: now + delay };
}
return { state: "review" };
}
I ran the model against five fixtures: first and later 4xx attempts, a 550, a 250, and a temporary failure at the expiry boundary. All five state transitions matched the expected result.
The production record needs more than the function shows: queue ID, recipient, envelope sender, first and last attempt times, next-attempt time, route tried, SMTP stage, raw reply, enhanced status, attempt count, and final DSN state. Store the diagnostic even after success or expiry. It is the difference between “email was delayed” and an incident you can explain.
Where does email verification stop?
Pre-send verification can identify address, domain, and mailbox evidence before you enqueue a message. It cannot guarantee that a later delivery avoids congestion, throttling, policy blocks, routing changes, or mailbox quota limits. A temporary probe result should remain unknown rather than becoming a permanent mailbox claim.
The send-time system owns the next step. Queue 4xx and temporary transport failures, stop on recipient-scoped 5xx, end your responsibility after a valid 2xx handoff, and let authenticated delivery reports update a separate suppression model. That keeps retry scheduling, mailbox evidence, and long-term address policy from collapsing into one unreliable Boolean.