D. J. Bernstein
Internet mail
SMTP: Simple Mail Transfer Protocol

Requests, verbs, parameters, responses, and codes

An SMTP conversation consists of requests and encoded messages sent by the client and responses sent by the server.

After the client connects, the server sends a response to the client, either accepting, temporarily rejecting, or permanently rejecting the connection. This initial response is called the server's greeting.

If the server accepts the connection, the client sends zero or more requests to the server. Each request is handled as follows:

  1. The client sends the request to the server.
  2. The server sends a response to the client, either accepting, temporarily rejecting, or permanently rejecting the request.
  3. Under some circumstances, if the server accepts the request, the client then sends an encoded message to the server, and the server sends another response to the client, either accepting, temporarily rejecting, or permanently rejecting the message.
The client must not send a request or an encoded message until it has received the previous response. (Exception: see the PIPELINING extension.) If sendmail receives a MAIL request in the same packet as the next request, it will send an extra response to the client. This loss of synchronization can easily corrupt or destroy mail.

Request format

A request is a string of bytes. It contains
  1. a verb consisting of alphabetic ASCII characters;
  2. optionally, a space followed by a parameter; and
  3. \015\012.
Some clients fail to include the \015, so I recommend that servers look only for \012. The parameter cannot contain \012.

For example, the following request (shown without the \015\012) contains verb HELO with parameter heaven.af.mil:

     HELO heaven.af.mil
A request with verb HELO is called a ``HELO request''; similar comments apply to ``MAIL request'' and so on.

RFC 821 requires that every server support the HELO, RSET, NOOP, MAIL, RCPT, DATA, and QUIT verbs. I also recommend that servers accept VRFY and EHLO requests and announce the PIPELINING and 8BITMIME extensions. Klensin requires that ``contemporary'' servers support EHLO.

Request semantics

The meaning of a request depends on (1) the verb and (2) the parameter. The format of the parameter depends on the verb.

RFC 821 specified that all verbs are interpreted without regard to case; so HELO and helo and Helo and hElO have the same meaning. However, a few SMTP servers do not follow this rule. Today's SMTP clients send verbs in uppercase; I recommend that new SMTP clients do the same thing.

Response format

The server's response is a sequence of one or more lines. Each line contains
  1. three ASCII digits;
  2. a single byte: viz., a space on the last line of the response, a hyphen on all previous lines;
  3. zero or more bytes of ``text''; and
  4. \015\012.
Some servers (e.g., AltaVista Firewall version 1.14) fail to include the \015, so I recommend that clients look only for \012. This means that \012 cannot be used inside ``text.'' It is also unsafe to use \0 inside ``text.''

According to rumor, some servers leave out the space on the last line of the response when there is no text.

RFC 821 prohibits response lines longer than 512 bytes, and requires that all clients be able to handle 512-byte response lines.

Each line of the response must start with the same three ASCII digits. The digits form a code. Codes between 200 and 399 indicate acceptance; codes between 400 and 499 indicate temporary rejection; codes between 500 and 599 indicate permanent rejection.

For example, the following three-line response uses code 250 to indicate acceptance:

     250-heaven.af.mil
     250-PIPELINING
     250 8BITMIME

RFC 821 prohibited all codes other than 211, 214, 220, 221, 250, 251, 354, 421, 450, 451, 452, 500, 501, 502, 503, 504, 550, 551, 552, 553, and 554. (Typically the second digit is 0 for a syntax error, 1 for a human-oriented help message, 2 for a hello/goodbye message, or 5 for a mail-related message.) Other codes will be misinterpreted by existing clients; for example, MMDF interprets code 471 as permanent rejection.

However, clients cannot take this list seriously. For example, some servers use code 571, in violation of RFC 821. (Apparently some people are under the delusion that RFC 1893 extended the list of SMTP codes. RFC 1893 clearly states that its codes---which aren't 3-digit numbers---are for use in a different context, namely DSNs.) The IETF subsequently permitted codes 252 and 555, again violating RFC 821.

I recommend that clients avoid looking past the first digit of the code, either 2, 3, 4, or 5. The other two digits and the text are primarily for human consumption. (Exception: See EHLO.)

A few clients are unable to handle responses longer than one line to verbs other than EHLO, HELP, and EXPN, even though RFC 821 permits multiple-line responses under all circumstances. Simeon 4.1.5 is unable to handle a multiple-line greeting. I recommend that servers use one-line responses whenever possible.

Syntax errors

Servers must reject unrecognized verbs. The IETF introduced EHLO after RFC 821 was published; it assumed that all existing servers would reject EHLO requests. More names might be introduced in the future.

Servers use code 500 or 502 to reject unrecognized verbs.

RFC 821 requires that all servers be able to handle 512-byte requests. Some servers allow much longer requests; other servers reject those requests with code 500. Some extensions require requests longer than 512 bytes.