Simple Mail Transfer Protocol · RFC 5321 · port 25 / 465 / 587
What is SMTP?
SMTP (Simple Mail Transfer Protocol) is the standard protocol for sending email across the internet. Defined in RFC 5321, it operates as a push protocol: a client connects to a server and delivers a message. SMTP handles only delivery — reading mail uses IMAP or POP3.
Every internet email travels through at least two SMTP hops: your mail client → your mail server (submission), then your mail server → the recipient's mail server (relay). Each hop adds a Received: trace header.
Key facts
1982
RFC 821 (original)
5321
Current RFC
25
MTA relay port
587
Submission port
465
SMTPS (implicit TLS)
ASCII
Original encoding
Mail delivery path
1
MUA → MSA — Mail User Agent (Outlook, Thunderbird) submits to Mail Submission Agent on port 587 with AUTH credentials.
2
MSA → MTA — Submission server hands off to the outbound Mail Transfer Agent (MTA), which looks up the recipient domain's MX record in DNS.
3
MTA → MTA — Sender's MTA connects to recipient's MTA on port 25 and delivers the message over an authenticated, TLS-encrypted session.
4
MTA → MDA — Recipient's MTA passes the message to the Mail Delivery Agent (MDA), which stores it in the mailbox for retrieval over IMAP/POP3.
# TCP connect to port 587220 mail.example.com ESMTP Postfix (Ubuntu)← server greetingEHLO client.sender.com← identify + request extensions250-mail.example.com250-PIPELINING250-SIZE 52428800250-STARTTLS250-AUTH PLAIN LOGIN250 8BITMIMESTARTTLS← upgrade to TLS220 2.0.0 Ready to start TLS… TLS handshake …EHLO client.sender.com← re-identify after TLS250-AUTH PLAIN LOGIN250 SIZE 52428800AUTH PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk← base64("\0user\0pass")235 2.7.0 Authentication successfulMAIL FROM:<alice@sender.com> SIZE=1024← envelope sender250 2.1.0 OkRCPT TO:<bob@example.com>← envelope recipient250 2.1.5 OkDATA← begin message body354 End data with <CR><LF>.<CR><LF>From: Alice <alice@sender.com>
To: Bob <bob@example.com>
Subject: Hello
Date: Thu, 10 Apr 2025 12:00:00 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Hello Bob, this is a test message.
.← single dot = end of message250 2.0.0 Ok: queued as A1B2C3QUIT221 2.0.0 Bye
Envelope vs message headers
Envelope MAIL FROM
Used by MTAs for routing and bounce delivery. Never seen by end user. Also called the "return path" or "5321.From".
Envelope RCPT TO
The actual delivery destination. May differ from the To: header (e.g. BCC, mailing lists, forwarding).
Header From:
What the recipient sees in their mail client. Must match SPF/DKIM domain to pass authentication. Also called "5322.From".
Header To:
Display recipient. Does not control delivery — RCPT TO does.
DATA termination
The message body ends with a line containing only a single period (.). If a line in the body starts with a period, the sender must "dot-stuff" it by prepending an extra period — the receiver strips the extra period.
Core SMTP commands (RFC 5321)
EHLO domain
Open session and announce extensions. Replaces HELO. Server responds with supported capabilities.
HELO domain
Legacy greeting — no extensions. Use EHLO unless connecting to a very old server.
MAIL FROM:<addr>
Start a new mail transaction. Sets the envelope sender (return-path). Optional SIZE= parameter.
RCPT TO:<addr>
Specify a delivery recipient. Repeat for multiple recipients. Server may reject unknown users here.
DATA
Begin transferring message headers and body. Server replies 354. Terminate with a lone period on its own line.
QUIT
Close the session gracefully. Server replies 221 and closes the connection.
RSET
Abort the current mail transaction without closing the connection. Clears MAIL FROM and RCPT TO state.
NOOP
No operation — keep connection alive and verify the server is still responsive. Server replies 250.
VRFY user
Verify that a mailbox exists. Most servers disable this to prevent user enumeration.
EXPN list
Expand a mailing list alias. Nearly always disabled on public servers.
HELP [cmd]
Request information about supported commands. Optional and often disabled.
ESMTP extensions (announced in EHLO response)
STARTTLS
RFC 3207. Upgrade plaintext connection to TLS in-place. Must EHLO again after upgrade.
AUTH mechanisms
RFC 4954. Client authentication. Common mechanisms: PLAIN, LOGIN, CRAM-MD5, XOAUTH2.
SIZE bytes
RFC 1870. Server announces max message size. Client may include SIZE= in MAIL FROM.
8BITMIME
RFC 6152. Server accepts 8-bit data in message body (not just 7-bit ASCII).
PIPELINING
RFC 2920. Client may send multiple commands without waiting for each response, improving throughput.
DSN
RFC 3461. Delivery Status Notifications — request success/failure receipts.
SMTPUTF8
RFC 6531. Internationalized email addresses using UTF-8.
CHUNKING / BDAT
RFC 3030. Binary transfer in chunks — avoids dot-stuffing for large messages.
AUTH mechanisms
AUTH PLAIN
Single base64 string: \0username\0password. Simple but credentials are base64, not encrypted — always use over TLS.
AUTH LOGIN
Server prompts for username then password separately, each base64-encoded. Obsolete; prefer PLAIN over TLS.
AUTH CRAM-MD5
Challenge-response using HMAC-MD5. Does not expose password in transit but MD5 is considered weak.
AUTH XOAUTH2
OAuth 2.0 Bearer token. Used by Gmail, Outlook 365. Token format: user=u\x01auth=Bearer TOKEN\x01\x01.
2xx — Positive completion
211
System status — response to HELP or STATUS command.
214
Help message — information on how to use the server.
220
Service ready — server greeting, sent immediately on connect.
221
Closing transmission channel — response to QUIT.
235
Authentication successful — AUTH accepted.
250
Requested action OK — most common success code. Used for EHLO, MAIL FROM, RCPT TO, message accepted.
251
User not local, forwarding — RCPT TO accepted but will be relayed.
252
Cannot verify, will attempt delivery — VRFY couldn't confirm but will try delivery.
3xx — Positive intermediate
334
AUTH challenge — server is sending a base64-encoded challenge (AUTH LOGIN, CRAM-MD5).
354
Start mail input — response to DATA. Server ready to receive message; end with <CRLF>.<CRLF>.
4xx — Transient negative (retry later)
421
Service not available — server shutting down or too busy. MTA should retry.
450
Mailbox unavailable — temporary issue, e.g. mailbox locked. Retry later.
451
Local error in processing — often greylisting or policy checks. Retry after delay.
452
Insufficient storage — disk full or message quota exceeded temporarily.
454
TLS not available — response to STARTTLS when TLS cannot be offered right now.
5xx — Permanent negative (do not retry)
500
Syntax error — command not recognized.
501
Bad parameters — command syntax OK but arguments are invalid.
502
Command not implemented — server doesn't support this command.
503
Bad sequence — command out of order, e.g. DATA before RCPT TO.
504
Parameter not implemented — command known but parameter unsupported.
521
Host does not accept mail — server exists but is not accepting mail.
535
Authentication failed — wrong credentials or mechanism not accepted.
541
No valid recipients — all RCPT TO addresses were rejected.
550
Mailbox unavailable — address doesn't exist or policy rejection. Most common bounce code.
551
User not local — server won't forward; try the indicated address.
552
Storage limit exceeded — recipient mailbox is full (permanent).
553
Mailbox name not allowed — address syntax invalid or not permitted.
554
Transaction failed — catch-all for policy failures, spam rejection, blacklisting.
556
Domain does not accept mail — null MX record (RFC 7505); destination explicitly refuses email.
SMTP port assignments
25
SMTP — MTA relay
Server-to-server mail transfer between MTAs. Authenticated clients should NOT use port 25. Most ISPs block outbound port 25 to prevent spam.
MTA only
587
SMTP Submission (STARTTLS)
RFC 6409. The correct port for mail clients and applications to submit email. Requires AUTH. Starts plaintext then upgrades to TLS via STARTTLS.
Recommended
465
SMTPS — Implicit TLS
TLS wraps the entire session from the first byte (like HTTPS). Originally deprecated but revived by RFC 8314 (2018) as the preferred submission port alongside 587.
Recommended
2525
Alternate submission
Non-standard but widely supported by ESPs (SendGrid, Mailgun). Used when ISPs block 587. No RFC backing — check provider docs.
Non-standard
587 vs 465
587 STARTTLS
Connection starts plaintext. Client sends EHLO, server advertises STARTTLS, client upgrades in-band. If STARTTLS fails, client must abort.
465 Implicit TLS
TLS negotiated before any SMTP bytes. Simpler — no in-band upgrade. RFC 8314 recommends this for new implementations.
Port 25 abuse
Never submit client mail over port 25. It exists for MTA-to-MTA relay and has no authentication requirement by default. Almost all residential and cloud ISPs block outbound port 25 connections to combat spam. Use port 587 or 465 with AUTH.
Email authentication standards
SPF
Sender Policy Framework (RFC 7208) — a DNS TXT record that lists which IP addresses are authorized to send mail for a domain. Checked by the receiving MTA against the envelope MAIL FROM domain.
Example: v=spf1 include:_spf.google.com ~all
DKIM
DomainKeys Identified Mail (RFC 6376) — adds a cryptographic signature to message headers. The signing domain publishes a public key in DNS. Receivers verify the signature, proving the message wasn't tampered with in transit.
Domain-based Message Authentication, Reporting and Conformance (RFC 7489) — builds on SPF and DMARC. Tells receivers what to do when checks fail: none / quarantine / reject. Enables aggregate reports.
STARTTLS (RFC 3207) upgrades an SMTP connection to TLS. Without policy enforcement, a man-in-the-middle can strip STARTTLS. MTA-STS (RFC 8461) solves this by publishing a policy that mandates TLS for inbound delivery, verified via HTTPS.
DANE (DNS-Based Authentication of Named Entities, RFC 7671) pins the TLS certificate expected on the SMTP server using a TLSA record in DNSSEC-signed DNS. TLSRPT (RFC 8460) provides failure reporting for MTA-STS and DANE.
# Find queue ID for a recipient
grep "to=<bob@example.com>" /var/log/mail.log | tail -20
# Follow a queue ID through the log
grep "QUEUEID" /var/log/mail.log
Check if an IP is blacklisted (DNSBL)
# Reverse the IP octets and query a DNSBL# For IP 1.2.3.4:
dig 4.3.2.1.zen.spamhaus.org +short
dig 4.3.2.1.bl.spamcop.net +short
Common diagnostic tools
swaks
Swiss Army Knife for SMTP. Full-featured test tool: TLS, AUTH, attachments, custom headers.
openssl s_client
Test TLS handshake and inspect server certificates. Use -starttls smtp for STARTTLS.
mailx / mail
UNIX CLI mail sender. Quick one-liner tests: echo "body" | mail -s "subject" user@host.