The SMTP conversation
Send message data
Enter DATA mode, terminate a message correctly, and understand why lines beginning with a dot are escaped.
8 minute lesson
After at least one recipient is accepted, the client sends DATA. A 354 reply means the server is ready for the message headers and body.
The client ends the data with <CRLF>.<CRLF>: a line containing only one dot. If a real message line starts with a dot, the client adds another dot. The receiving SMTP server removes it. This is called dot-stuffing.
The final 250 is important. It says the receiving server accepted responsibility for that message. A dropped connection before that reply leaves the sender uncertain and may cause a retry.
The transformation is visible on the wire:
Message line: .status is ready
Wire line: ..status is ready
Terminator: .
The server removes one leading dot from every dot-stuffed line. The terminator is not part of the RFC 5322 message. SMTP libraries handle this; application code should not add dots to the stored message itself.
After 354, a normal server expects message content, not another SMTP command. If it detects a size or policy failure while receiving data, it reports the transaction result after the terminator. The client must read that final reply before it reuses the connection or removes its queued copy.
An uncertain disconnect is an at-least-once problem. The server may have committed the message just before the connection failed. A retry can produce a duplicate, so receivers and applications should not treat Message-ID as a perfect deduplication guarantee, but it can help identify repeats.
Write a five-line message containing a line that begins with a dot. Show the stored form, the wire form, and the final SMTP terminator separately.
Lesson completed