emailmarketing.net

RFC 5321 — SMTP: The Transport Protocol

Deliverability-focused digest of SMTP: session model, envelope vs. content, reply-code semantics, null sender, retry rules, size limits, and timeouts.

Foundationalesp-operatorsender

RFC 5321 defines how mail moves between hosts. Every bounce code, retry policy, and envelope-level identity used in deliverability work traces back to this spec. For the surrounding vocabulary (MTA, MSA, ADMD…), see RFC 5598 — Internet Mail Architecture; for the message inside the envelope, see RFC 5322 — Message Format.

Session model

An SMTP session is a lock-step, one-command-at-a-time dialog (extensions like PIPELINING relax this by mutual agreement):

Step Client sends Server success reply
Connect (TCP connection) 220 greeting
Identify EHLO client-hostname (fallback HELO) 250 + extension list
Envelope sender MAIL FROM:<reverse-path> 250
Envelope recipient(s) RCPT TO:<forward-path> (one per recipient, repeatable) 250 (or 251 forwarded)
Content DATA 354 — then message, terminated by <CRLF>.<CRLF>, then 250
End QUIT 221

Other commands: RSET (abort current transaction), VRFY/EXPN (address verification — widely disabled or answered 252 for anti-harvesting reasons), NOOP, HELP.

  • A rejection at MAIL FROM/RCPT TO costs the receiver nothing per-message; a rejection after DATA means the receiver already accepted the bytes. Many providers defer final judgment (content filtering) to the post-DATA reply — a 5xx after the final dot is a content/reputation rejection, not an address problem.
  • The EHLO hostname is an identity signal: receivers commonly check that it is a resolvable FQDN and consistent with the connecting IP's rDNS. RFC 5321 requires it to be the client's primary host name (or an address literal when none exists).

Envelope vs. content

The envelope is the protocol-level addressing: one reverse-path (MAIL FROM) plus one or more forward-paths (RCPT TO). The content is everything sent inside DATA: header section + body (governed by RFC 5322).

Consequences that matter constantly in deliverability:

  • The address people see (From: header) and the address bounces go to (MAIL FROM, recorded on delivery as Return-Path:) are independent. SPF authenticates the envelope MAIL FROM; DMARC then tests its alignment with the header From: — see DMARC.
  • RCPT TO recipients need not appear in To:/Cc: (this is how Bcc and list expansion work).
  • Relays MUST NOT modify the envelope addresses or message semantics; they only prepend trace fields (Received:; the final delivery agent prepends Return-Path:).

Reply codes

Three digits; the text after the code is for humans, the number is the contract.

First digit Class Sender behavior
2yz Positive completion Action succeeded; proceed
3yz Positive intermediate Send more (only 354 in base SMTP)
4yz Transient negative Failure may clear; retry later, unchanged
5yz Permanent negative Do not retry the same request; bounce/suppress

Second digit: x0z syntax, x2z connections, x5z mail system status. Modern servers append RFC 3463 enhanced status codes (5.7.1 etc.) after the three-digit code for finer diagnosis.

Key codes:

Code Meaning
220 Service ready (greeting)
221 Closing channel (after QUIT)
250 Requested action OK / completed
251 User not local; will forward to <forward-path>
252 Cannot VRFY user, but will accept and attempt delivery
354 Start mail input; end with <CRLF>.<CRLF>
421 Service not available, closing channel (also used for rate limiting / greylisting-style deferrals)
450 Mailbox unavailable (temporary — e.g., busy, greylisted)
451 Local error in processing; retry later
452 Insufficient system storage / too many recipients — retry
455 Server unable to accommodate MAIL parameters now
500504 Syntax error / command not implemented / bad parameters
550 Mailbox unavailable (permanent — unknown user, policy rejection)
551 User not local; try <forward-path>
552 Exceeded storage allocation (message too big for mailbox)
553 Mailbox name not allowed (bad address syntax)
554 Transaction failed (no valid recipients / content or policy rejection)
555 MAIL FROM/RCPT TO parameters not recognized

Deliverability reality check: receivers legally use any code with any text — 4xx deferrals ("try again later", "unusual rate of mail") are the standard soft signal of reputation throttling, and 550 5.7.x texts carry the provider's actual reason. Always log full reply text, not just the code.

Null reverse-path (MAIL FROM:<>)

  • Delivery status notifications (bounces) and other MHS-generated notifications MUST be sent with a null reverse-pathMAIL FROM:<> — so that failed bounces can never generate further bounces (loop prevention).
  • Servers MUST accept MAIL FROM:<>; rejecting the null sender breaks bounce handling and is noncompliant (though some spam filters score it).
  • A message received with a null reverse-path must never itself be answered with a DSN to that path.
  • Practical corollary: any address you use in MAIL FROM must be able to receive mail (bounce processing); the null sender is only for notifications, never for regular sending.

Retry expectations (Section 4.5.4)

  • After a 4xx or connection failure, the sender queues and retries. The retry interval SHOULD be at least 30 minutes per destination (a strategy that shortens this when the first attempt failed mid-connection is permitted).
  • Give-up time generally needs to be at least 4–5 days, after which a permanent failure notification goes to the reverse-path.
  • Retries MUST be per destination host/address, with exponential-style backoff encouraged; hammering a deferring host is itself a reputation signal.
  • On 5xx, the sender MUST NOT retry the same message to the same address — generate a non-delivery notification instead. (For list hygiene: hard bounces get suppressed immediately; soft bounces get suppressed after repeated failures across the retry window.)
  • If multiple MX hosts exist, the client tries them in preference order (lowest MX value first) before deferring.

Size limits (Section 4.5.3.1 — minimums implementations MUST handle)

Object Minimum capacity
local-part 64 octets
domain 255 octets
path (<...> incl. punctuation) 256 octets
command line (incl. CRLF) 512 octets
reply line (incl. code + CRLF) 512 octets
text line (incl. CRLF) 1000 octets
message content at least 64K octets; no fixed ceiling — advertised via the SIZE extension (RFC 1870)

Exceeding a receiver's declared limits draws 552 (message) or 500 (line/command). Modern practice: check the SIZE= value in the EHLO response before sending large messages.

Timeouts (Section 4.5.3.2 — minimum client-side waits)

Waiting for Minimum timeout
Initial 220 greeting 5 minutes
MAIL reply 5 minutes
RCPT reply 5 minutes
DATA reply (354) 2 minutes
Each data block accepted 3 minutes
Reply to final <CRLF>.<CRLF> 10 minutes
(Server side) inactivity 5 minutes

The 10-minute end-of-data wait matters: providers deliberately delay the post-DATA verdict while filtering; clients that hang up early cause duplicate deliveries (server delivers, client retries).

See also

#rfc#smtp#protocol#bounce-codes#envelope#retry