SMTP
SMTP
Simple Mail Transfer Protocol. The protocol email clients use to send outbound messages to mail servers, and that mail servers use to relay messages to each other. Defined in RFC 5321 (with extensions in many other RFCs). Dates to 1982.
SMTP is a one-way push protocol: you connect, you submit a message, you disconnect. Reading mail uses IMAP or POP3 — different protocol, different port.
Wire format
A line-based ASCII protocol. Client issues commands; server responds with 3-digit status codes.
S: 220 mail.example.com ESMTP Postfix
C: HELO client.example.com
S: 250 mail.example.com
C: MAIL FROM:<alice@example.com>
S: 250 OK
C: RCPT TO:<bob@example.com>
S: 250 OK
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: alice@example.com
C: To: bob@example.com
C: Subject: hi
C:
C: Hello, Bob.
C: .
S: 250 OK
C: QUIT
S: 221 Bye
The DATA block is the entire RFC 5322 message — headers, blank line, body. Encoded per MIME for anything richer than ASCII text.
Ports
- 25 — server-to-server relay. Most ISPs block outbound 25 from residential IPs to fight spam.
- 587 — message submission. Authenticated, supports STARTTLS upgrade. The standard port for clients to use.
- 465 — implicit TLS submission. RFC 8314 recommends it for message submission.
- 2525 — common alternate when 587 is blocked.
Authentication
Modern SMTP submission requires authentication. Common mechanisms:
- PLAIN / LOGIN — username + password over TLS. Most common.
- CRAM-MD5 — challenge/response. Less common.
- OAuth2 (XOAUTH2) — Gmail, Outlook. The standard for modern providers. See OAuth for Email.
TLS modes
- STARTTLS — connection starts cleartext, client issues
STARTTLS, connection upgrades to TLS. Port 587. - Implicit TLS — TLS from the first byte. Port 465.
- Cleartext — only for test/dev. Real mail submission is always TLS-protected.
What mxr does
Per Mxr's crates/provider-smtp/src/lib.rs:
- Library:
lettre(async SMTP for Tokio). - With
use_tls = true, port 465 uses implicit TLS; every other port uses STARTTLS.use_tls = falseis plaintext. - Auth is optional but normally required. mxr refuses
auth_required = truewith plaintext transport, so it cannot submitPLAINorLOGINcredentials without encryption. - IMAP/SMTP passwords come from the profile's
0600secrets.toml. The OS keychain is a migration fallback rather than the normal read path. - Message construction in
crates/outbound/src/email.rs: multipart/alternative with text+HTML, optional multipart/mixed wrapper for attachments. FreshMessage-ID: <uuid@domain>per send. Threading headers (In-Reply-To,References) populated from the draft.
Common pitfalls
- DKIM/SPF/DMARC — sending mail from your own domain requires these to be set up correctly or recipients (especially Gmail) treat your mail as spam. mxr doesn't help with this; it's domain configuration.
- Aliases need provider permission — a client can put an address in the message
From:header and SMTP envelope, but the authenticated provider may reject it unless that mailbox or send-as alias is configured there. A local owned-address registry is not proof of provider authorization. See Local Identity Registration Is Not Provider Authorization. - Transient rejection — SMTP 4xx responses and timeouts are classified as retryable with a 60-second backoff hint. A caller still has to schedule or retry the operation.
- Connection drops mid-DATA — message may or may not have been accepted. Idempotency is the client's problem; usually solved by tracking sent messages with a unique Message-ID.
- Submission rate limits — providers throttle. Burst sends can get throttled or blocked.
SMTP vs alternatives
- POP3 / IMAP — for reading, not sending. Different protocols entirely.
- JMAP — newer (2019) JSON-RPC protocol for both sending and reading. Designed to replace SMTP+IMAP. Adoption is sparse outside Fastmail.
- Gmail / Microsoft Graph APIs — proprietary REST APIs that handle send. mxr uses Gmail's API for Gmail accounts; SMTP for everything else.
See also
- IMAP — the read counterpart
- MIME — the message body format SMTP carries
- OAuth for Email — modern auth for SMTP
- How Email Actually Works — synthesis
- Mxr — concrete reference implementation
- Local Identity Registration Is Not Provider Authorization — why a local alias record is only one of two gates
- RFC 5321: https://datatracker.ietf.org/doc/html/rfc5321