Summary

  • SMTP's single positive reply after message data accepts the transaction as a whole; it cannot immediately report that local delivery succeeded for one accepted recipient and temporarily failed for another.
  • RFC 2033's LMTP returned one ordered final reply for every successful RCPT, letting an upstream queue manager retain unresolved recipients while exposing a residual duplicate risk whenever delivery completes but its reply is lost.

One body produced two different truths

Imagine a queue manager handing one message to a local mailbox service. It issues two RCPT commands, and both receive a preliminary 250. Only after the complete body arrives does the service perform the work that matters. The first mailbox accepts the message. The second is temporarily over quota.

Ordinary SMTP cannot end that DATA exchange with both 250 and 452. Its final reply applies to the transaction. Under the current model in RFC 5321, the end-of-data decision has no partial-failure grammar: the server either accepts the message for delivery or does not. If it answers positively, it takes full responsibility. A failure discovered later for one recipient must be handled by retry or a later notification, not by pretending one final status meant two things.

That rule is well suited to store-and-forward mail between networked hosts. A receiving SMTP server owns a queue precisely so it can accept now and finish later. It becomes a problem at a different seam: the handoff from an existing queue manager to a local delivery agent. Requiring that agent to run another durable queue duplicates responsibility, storage and recovery logic merely because the protocol has too few final replies.

The Local Mail Transfer Protocol changed that seam rather than redesigning Internet mail.

The number of replies moved the queue boundary

RFC 2033, published as Informational in October 1996, defined LMTP for limited situations in which the client already manages a queue and the server should not. After the final DATA dot, an LMTP server returns one reply for each previously successful RCPT command, in the same order those commands were issued.

That small change alters the custody ledger. If recipient A receives a final 250, the delivery agent has accepted responsibility for A. If recipient B receives 452, the queue manager retains B for another attempt. The original message need not be handed to a second general-purpose queue, and the first queue need not retry a recipient that has an acknowledged positive result.

The mapping is positional. A recipient rejected during RCPT is absent from the final-reply sequence. Two successful RCPT commands naming the same forward path still require two replies. A multiline response remains one response. The client therefore has to preserve the exact ordered list of successful recipients; matching later by address text is not an equivalent implementation.

LMTP did not make a provisional RCPT acceptance into a delivery promise. The decisive transfer still happens after the content has arrived and the corresponding final reply is positive.

A different greeting guarded a different grammar

LMTP resembles ESMTP closely enough that silent confusion would be dangerous. A client expecting one SMTP result could read the first LMTP recipient reply as the end of the transaction and leave later replies attached to the wrong command. An LMTP client expecting several results could wait forever after an SMTP server's single final answer.

RFC 2033 therefore replaced HELO and EHLO with LHLO. An LMTP server must not positively accept the SMTP greetings, and LMTP must not use SMTP's service port 25. These are not branding details. They make the reply contract visible before the message enters it.

The specification also required PIPELINING and enhanced status codes. RFC 2920 preserves reply order when commands are sent without waiting between them; RFC 2034 and RFC 3463 provide more structured failure meaning. Neither replaces the recipient ledger. A precise 4.2.2-style status is useful only after the client knows which successful RCPT position it belongs to.

When CHUNKING is available, BDAT LAST receives the same per-recipient treatment. Earlier BDAT chunks still get one reply each. The special cardinality attaches to completion of the message, not to every piece of its framing.

The old duplicate gap became smaller, not impossible

LMTP's precision does not create an atomic commit between a mailbox write and a network acknowledgment. RFC 1047 had already described the SMTP synchronization gap: after a receiver has accepted or delivered a message but before the sender receives its positive reply, both sides can hold a reasonable but conflicting view of responsibility. If the connection fails there, retry can duplicate the message.

With LMTP, that gap exists separately for each unresolved recipient. Suppose A's 250 reaches the queue manager and is durably processed. A can be removed from the retry set. Now suppose the local agent delivers to B, but the connection closes before B's positive reply arrives. The client has no transferable proof that B was accepted. RFC 2033 requires it to process the replies that did arrive and treat the rest as temporary failures. Retrying B can produce a second copy.

The specification addresses exposure rather than claiming to abolish it. The server should send each reply as soon as possible and flush before spending substantial time on the next recipient. The client should process replies as they arrive instead of waiting for the entire batch. Those rules reduce the ambiguous suffix of the recipient list when a connection breaks.

They cannot retract a mailbox write whose acknowledgment was lost. Exactly-once delivery would require a durable shared transaction across systems, not a better arrangement of SMTP reply lines.

Locality was part of the safety model

RFC 2033 advises against using LMTP over wide-area networks. That boundary follows from its purpose. The upstream queue manager is the durable retry authority; the downstream agent performs close, recipient-specific delivery. A long, failure-prone path increases the chance that work completes while its reply disappears and makes the queue manager's immediate knowledge less reliable.

The RFC goes further: a server that can rapidly accept responsibility for all recipients and can generate necessary notifications should not implement LMTP. Such a server already behaves like a queue-owning SMTP receiver. Per-recipient blocking replies would add synchronization exposure without removing useful queue complexity.

LMTP is therefore not “SMTP with better error messages.” It is a declaration about where durable responsibility belongs. Its advantage appears only when the client already owns the queue and the server has more accurate local delivery truth but should not retain unresolved work.

Immediate verdicts were not delivery reports

A later Delivery Status Notification describes an event after another system has accepted responsibility. An LMTP final reply participates in the handoff itself. A temporary LMTP result tells the current queue manager that responsibility did not transfer for that recipient. A positive result says that it did.

Neither statement proves that a human read the message, that a user interface displayed it or that the address names the intended person. The protocol accounts for transport responsibility. It does not turn a mailbox result into identity or attention.

This distinction keeps LMTP separate from the history of DSNs. The notable invention was not a richer report for the sender. It was a final exchange granular enough to prevent one local failure from forcing a second all-recipient queue.

Sources and evidence limits

The closed source set is RFC 1047, RFC 2033, RFC 2034, RFC 2920, RFC 3463 and RFC 5321. They establish protocol grammar, responsibility and failure boundaries. They do not measure current deployment, vendor defaults, incident rates or a universal transport socket. RFC 2033 is Informational; this account does not turn its limited design into an Internet-wide mandate.