How an SMTP conversation works, step by step
When you press Send, your mail server holds a short text conversation with the receiving server. Seeing it line by line makes bounce messages, ports and authentication much easier to understand.
An SMTP session has five stages: the servers greet each other (EHLO), switch on encryption (STARTTLS), name the sender and recipients (MAIL FROM, RCPT TO), send the message (DATA) and hang up (QUIT). Every command gets a three-digit reply: 2xx means OK, 3xx means "go on", 4xx is a temporary failure and 5xx a permanent one.
A complete example
Here a mail server sends one message to example.org. C: is the sending client, S: the receiving server. The addresses and names are made up.
S: 220 mx.example.org ESMTP ready
C: EHLO mail.example.com
S: 250-mx.example.org Hello
S: 250-SIZE 36700160
S: 250-8BITMIME
S: 250 STARTTLS
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
(encryption starts; the client says EHLO again)
C: EHLO mail.example.com
S: 250 mx.example.org Hello
C: MAIL FROM:<[email protected]>
S: 250 2.1.0 OK
C: RCPT TO:<[email protected]>
S: 250 2.1.5 OK
C: DATA
S: 354 Go ahead, end with <CRLF>.<CRLF>
C: From: Alex <[email protected]>
C: To: Sam <[email protected]>
C: Subject: Lunch on Friday?
C:
C: Are you free at noon?
C: .
S: 250 2.0.0 OK: queued as 7F3A2
C: QUIT
S: 221 2.0.0 ByeWhat each step does
| Command | What it does |
|---|---|
220 greeting | The receiving server says it's ready. |
EHLO | The client introduces itself by hostname. The reply lists what the server supports, such as its size limit and STARTTLS. |
STARTTLS | Upgrades the connection to an encrypted one. See TLS vs STARTTLS. |
AUTH | Only when your app sends to your own provider (port 587 or 465): signs in with your username and password or an OAuth token. Servers don't use AUTH to deliver to each other. |
MAIL FROM | The envelope sender: where bounces go. It becomes the Return-Path header, and SPF checks its domain. |
RCPT TO | One line per recipient. This is where "user unknown" (550 5.1.1) is usually returned. |
DATA | The message itself: headers, a blank line, then the body, ending with a line containing only a dot. |
QUIT | Ends the session. |
Envelope vs headers: why they can differ
The addresses in MAIL FROM and RCPT TO are the envelope, like the address on a paper envelope. The From and To lines inside DATA are the letter. They don't have to match:
- Bcc works because a Bcc recipient is in RCPT TO but not in the To or Cc headers.
- Newsletters often use a bounce address such as [email protected] in MAIL FROM while showing [email protected] in From. DMARC checks that the two domains line up.
Where errors happen
A refusal can come at any step, and the step tells you a lot:
- At connection or EHLO: usually a blocklist or reputation problem (5.7.1, 4.7.0).
- At AUTH: wrong password or sign-in turned off (535 5.7.8, 535 5.7.139).
- At RCPT TO: the address is wrong (550 5.1.1).
- After DATA: content, size or authentication checks (5.7.26, 5.3.4).
Look up any code in the SMTP error code library.
Ports used by SMTP
| Port | Used for |
|---|---|
| 25 | Server-to-server delivery (as in the example above). Usually blocked on home internet connections. |
| 587 | Your app sending to your provider, with STARTTLS and sign-in. |
| 465 | Your app sending to your provider, encrypted from the first byte. |
Questions people ask
- What is the difference between HELO and EHLO?
- EHLO is the extended version, used by modern servers. It asks the receiving server to list the features it supports, such as STARTTLS and size limits. HELO is the original command with no feature list.
- Can I test SMTP by hand?
- Yes, with tools such as openssl s_client or swaks, but only against servers you're allowed to test. Many networks block port 25.
- Why does the message end with a single dot?
- A line with just a dot tells the server the message is complete. If a line in your message starts with a dot, the sending app adds a second dot so it isn't mistaken for the end.
Sending one email to a whole list? Check the addresses first with Veml, which removes bad and risky emails before you hit send. (Veml and EmailNa have the same owner.)