Simple Mail Transfer Protocol (SMTP)

The Simple Mail Transfer Protocol (SMTP) is the protocol mail servers use to hand messages to one another, and that mail clients use to submit new messages for sending. It is defined in RFC 5321.

SMTP is a line-based conversation in plain text. That is worth knowing not out of nostalgia but because every rejection you will ever debug is a line from this conversation, quoted back at you in a log file.

What does an SMTP session look like?

Client lines are the commands; the numbered lines are the server’s replies:

$ telnet mx1.example.net 25
220 mx1.example.net ESMTP Postfix
EHLO mail.example.com
250-mx1.example.net
250-PIPELINING
250-SIZE 20480000
250-STARTTLS
250 8BITMIME
MAIL FROM:<sender@example.com>
250 2.1.0 Ok
RCPT TO:<recipient@example.net>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: Sender <sender@example.com>
To: Recipient <recipient@example.net>
Subject: Test

This is the message body.
.
250 2.0.0 Ok: queued as 4Rk8Zt1234
QUIT
221 2.0.0 Bye

Every acceptance decision a receiving server makes happens at one of those steps, which is why “where in the conversation was it rejected” is the first question when mail goes missing.

What is the envelope, and why does it differ from the headers?

MAIL FROM and RCPT TO are the envelope. They are what the servers act on: where a bounce goes and where the message is actually delivered.

From:, To: and Cc: are headers. They are part of the message content and are what the recipient sees. Nothing in SMTP requires the two to agree.

This gap is not a flaw so much as a design: it is what makes mailing lists and Bcc work. It is also the root of a great deal of abuse, and the reason SPF authenticates the envelope while DMARC exists to tie that result back to the visible From:.

What do the response codes mean?

Class Meaning Sender’s reaction
2xx success continue
3xx intermediate, send more continue
4xx temporary failure retry later, keep queued
5xx permanent failure give up, generate a bounce

The distinction between 4xx and 5xx decides everything downstream. A 450 keeps the message in the queue for retry; a 550 produces a non-delivery report at once.

This is also the mechanism behind greylisting: a server answers 450 to an unknown sender on first contact, expecting a legitimate server to retry a few minutes later while a great deal of bulk-sending software never will.

Which ports are used, and for what?

Treating 25 and 587 as interchangeable is how a server becomes an open relay. See access management.

Where do the checks hook into the conversation?

Each stage is an opportunity to reject, and rejecting early is cheaper and safer:

Stage What is checked
connection client IP against local maps and DNSBLs
EHLO the hostname, and its reverse DNS
MAIL FROM envelope sender, SPF
RCPT TO does the recipient exist, is relaying permitted
DATA / end of data content scanning, DKIM verification, DMARC

Rejecting an unknown recipient at RCPT TO rather than accepting and bouncing afterwards is what prevents backscatter — the single most consequential configuration choice in this table.

How do you test an SMTP server by hand?

telnet or openssl s_client to the port and type the commands above. For TLS-only submission:

$ openssl s_client -connect mx1.example.net:465 -quiet
220 mx1.example.net ESMTP Postfix
EHLO mail.example.com

For scripted testing, sending through the local MTA is usually more convenient than speaking the protocol directly — see sending test emails from shell.