# ESMTP Extensions for Senders — SIZE, PIPELINING, CHUNKING, DSN

> What RFC 1870 SIZE, RFC 2920 PIPELINING, RFC 3030 CHUNKING/BINARYMIME, and RFC 3461 DSN (NOTIFY/RET/ENVID/ORCPT) do, and when each matters on an ESP's outbound path.

Source: emailmarketing.net — https://emailmarketing.net/learn/rfc/esmtp-extensions

If you run a sending MTA, four SMTP service extensions have a direct effect on your outbound throughput and on the quality of your bounce data: SIZE, PIPELINING, CHUNKING and DSN. Below is what each one does and when it matters.

ESMTP extensions are negotiated for each session. The server lists keywords in its `EHLO` response, and the client may then use the matching commands and parameters. A sending MTA should parse the EHLO extension list on every connection and adapt to it. Other extensions are covered elsewhere: 8BITMIME (RFC 6152) and SMTPUTF8 in [MIME & Encoding](https://emailmarketing.net/learn/rfc/mime-and-encoding) and [SMTPUTF8 and EAI](https://emailmarketing.net/learn/rfc/smtputf8-eai), and STARTTLS in [transport security](https://emailmarketing.net/learn/transport-security/mta-sts).

## RFC 1870 — SIZE (message size declaration)

- **EHLO keyword:** `SIZE`, with an optional numeric parameter giving the fixed maximum message size, in octets, that the server will accept. `SIZE 0` means there is no fixed maximum. `SIZE` with no number gives no information about a limit.
- **MAIL parameter:** `MAIL FROM:<...> SIZE=nnn` (1–20 digits). The declared size is the number of octets the client will send after the `354`, **including CRLF pairs but excluding the terminating dot and the extra dots added by dot-stuffing**. In other words, it is the headers and body as sent. An estimate is fine, and estimates should err on the high side.
- **Server replies:** `552` is permanent (the declared size exceeds the fixed maximum, so do not retry at that server). `452` is temporary (the server lacks resources right now, so retry later). The server may check the size at MAIL time or after DATA. It may accept a message larger than declared, and should not send a `552` after DATA unless the actual size exceeded the declared size.

**When it matters:** declaring SIZE turns an oversized send into a cheap rejection before DATA, instead of transferring megabytes and receiving `552` after the final dot. At scale, that saves real bandwidth and queue time. Reading the advertised limit lets the MTA fail oversized messages locally with a clear bounce ("exceeds example.com's 26214400-octet limit"), and lets a platform enforce composition limits for each destination.

Remember that the advertised limit applies to the **encoded** message, and base64 adds ~37% (see [MIME & Encoding](https://emailmarketing.net/learn/rfc/mime-and-encoding)). Distinguish the `552` from SIZE (the message is too big, a content problem) from the `552` "exceeded storage allocation" in RFC 5321 (the mailbox is full, a recipient problem). The enhanced status code tells them apart (`5.3.4` for the first, `5.2.2` for the second).

## RFC 2920 — PIPELINING (command batching)

- **EHLO keyword:** `PIPELINING`, with no parameters. Never pipeline commands to a server that did not advertise it.
- **What may be pipelined:** `RSET`, `MAIL FROM` and `RCPT TO` (and the obsolete SEND, SOML and SAML) may appear anywhere in a group. **`EHLO`, `DATA`, `VRFY`, `EXPN`, `TURN`, `QUIT` and `NOOP` may only be the last command in a group**, because their success or failure changes the session state. NOOP can be used as a synchronization point.
- **Client obligations:** check **every** status in the group, matching replies to commands by counting them. You MUST NOT assume that DATA failed just because all the RCPT commands failed: read its reply. Without nonblocking I/O, the client must keep each group within the TCP window to avoid a deadlock.
- **Server obligations:** reply in the order the commands were received. Buffer replies to commands that can be pipelined, but never to the commands that end a group. Send a positive `DATA` reply only if ≥1 valid RCPT was accepted. If the server replied 354 with no valid recipients, it must accept the message and discard it. Never flush the TCP input buffer.

**When it matters:** without pipelining, a transaction costs one round trip per command (`MAIL`, each `RCPT`, then `DATA`, for a total of N+2 round-trip times, or RTTs). With pipelining, `MAIL FROM`, all the `RCPT TO` commands and `DATA` go out in one write, about 1 RTT before the content. Over a 100 ms transatlantic path, that is the difference between ~3–4 messages per second per connection and ~10+.

Pipelining is the cheapest way for an outbound MTA to multiply its throughput before it adds connections, which [provider connection caps](https://emailmarketing.net/learn/providers/microsoft-sender-requirements) limit anyway. Almost all major receivers advertise it. One caution: some anti-spam layers treat "early talkers" (clients that send before the greeting banner, or pipeline without the extension being advertised) as bots. Negotiate strictly.

## RFC 3030 — CHUNKING (BDAT) and BINARYMIME

- **EHLO keywords:** `CHUNKING` (which enables `BDAT`) and `BINARYMIME` (binary content with no transfer encoding, usable **only** together with CHUNKING).
- **BDAT syntax:** `BDAT chunk-size [LAST]`. The exact number of octets follows immediately after the command's CRLF. There is no dot-stuffing and no scanning for a `<CRLF>.<CRLF>` terminator. The final chunk carries `LAST`, and it may be empty. The server MUST reply `250` to each successful chunk.
- **Errors:** if a failure occurs during the transaction, the server MUST still read and discard the announced chunk octets before it replies `4xx` or `5xx`. After any `4xx` or `5xx` reply to a BDAT command, the client MUST NOT send further BDAT segments, and should send `RSET` to clear the transaction.
- **Mixing rules:** `DATA` and `BDAT` MUST NOT be mixed in one transaction (`503`), although both may appear in different transactions of the same session. `BODY=BINARYMIME` on the MAIL command commits the transaction to BDAT, so `DATA` after it gets `503`. A receiver that accepts BINARYMIME must preserve every bit of every octet from then on. `text/*` content must still use CRLF line endings.

**When it matters:** for typical marketing mail, rarely. The messages are small and already safe as 7-bit, and several large receivers do not advertise CHUNKING, so the DATA path must exist anyway. CHUNKING matters for very large messages (no scanning for the terminator, and exact accounting), for truly binary payloads that would otherwise grow by base64's ~37%, and in some modern submission paths where BDAT is the native framing.

A note on interoperability: bugs in how filters and gateways handle BDAT have caused parsing discrepancies in the past (BDAT was a vector for SMTP smuggling at receivers), so some operators deliberately leave it off. Treat it as an optimization to enable for each destination, never as a requirement.

## RFC 3461 — DSN extension (NOTIFY / RET / ENVID / ORCPT)

This extension is the SMTP side of delivery status notifications. It controls **when** DSNs are generated and carries correlation data through to them. [RFC 3464](https://emailmarketing.net/learn/bounce-handling/delivery-status-notifications) defines the format of the bounce itself.

- **EHLO keyword:** `DSN`, with no parameters.

**Parameters for each recipient (`RCPT TO`):**

| Parameter | Values and syntax | Meaning |
|---|---|---|
| `NOTIFY` | `NEVER` \| a comma-separated list of `SUCCESS`,`FAILURE`,`DELAY` | `NEVER` must appear alone, and means no DSN under any conditions. `SUCCESS`: a DSN on delivery. `FAILURE`: a DSN on failure. `DELAY`: the sender is willing to receive DSNs about delays. If the parameter is absent, the receiver's default applies, which in effect is `FAILURE` or `FAILURE,DELAY` |
| `ORCPT` | `addr-type;xtext-address` (e.g. `rfc822;user+2Btag@example.com`), ≤500 characters | The original recipient as the sender specified it. It is passed on unchanged through forwarding, so the DSN's `Original-Recipient` field survives address rewrites. At submission it must match the RCPT TO address |

**Parameters for each message (`MAIL FROM`):**

| Parameter | Values and syntax | Meaning |
|---|---|---|
| `RET` | `FULL` \| `HDRS` | Whether failure DSNs return the whole message or only its headers (success DSNs return the headers at most). If absent, the receiver chooses |
| `ENVID` | xtext, ≤100 characters (user agents are advised to use ≤38) | An opaque transaction ID from the sender, returned unchanged in the DSN's `Original-Envelope-Id` field. It links a bounce directly to its send, without parsing message headers |

- **xtext encoding:** printable ASCII characters 33–126, except `+` and `=`, pass through unchanged. Every other character becomes `+HH` (uppercase hexadecimal). Values must be US-ASCII before encoding.
- **Effect on command lines:** a conforming MTA must handle command lines of at least 1036 characters (512 for the base command, plus 530 for the ORCPT and NOTIFY parameters on RCPT).
- **Server neutrality:** a server MUST NOT refuse a MAIL or RCPT command only because it carries valid DSN parameters. Malformed or duplicate parameters get `501`.
- **Relay rules:** when the next hop supports DSN, ENVID, RET, NOTIFY and ORCPT MUST be passed on exactly (ORCPT with its case preserved, and a relay may add ORCPT if it is absent). When the next hop does **not** support DSN, the parameters MUST NOT be sent, and the relaying client makes up for it instead. With `NOTIFY=SUCCESS` and the message accepted, it MUST generate a "relayed" DSN. On failure (5xx), it generates a "failed" DSN unless `NOTIFY=NEVER` was set. With `NOTIFY=NEVER`, no DSN is ever sent.
- **Mailing lists:** when a list redistributes a message, it MUST NOT carry the DSN parameters of the original submission. The list sets its own, with its own return path. Tracking of successful delivery therefore stops at the list: a submission with `NOTIFY=SUCCESS` gets its success DSN from the MTA that delivered it to the list.

**When it matters for an ESP:**

- **`NOTIFY=NEVER` is the most useful setting in practice.** RFC 3834 recommends it for auto-replies. It is equally useful for any traffic whose bounces you plan to detect another way, or do not want at all (for example, probe traffic). Where the receiver honors it, it stops non-delivery reports (NDRs) from being generated at the source. Do **not** use it on normal campaign mail, because you need failure DSNs for [bounce processing](https://emailmarketing.net/learn/bounce-handling/delivery-status-notifications).
- **`ENVID`** links each bounce to its message even when the returned content has been stripped. It complements VERP: VERP still works with bounces that do not follow RFC-3464, and ENVID still works through forwarders that break VERP. It costs little, so set it.
- **`RET=HDRS`** keeps failure DSNs small, which is polite and saves bandwidth when your messages are large.
- **`NOTIFY=SUCCESS` is not a tool for tracking delivery** at scale. Most large mailbox providers ignore it or do not send success DSNs, and requesting a success notification for every recipient of millions of messages would create a traffic problem of its own. Rely on SMTP acceptance and engagement signals instead.

## Reading an EHLO response: a checklist for senders

| Keyword seen | Sender action |
|---|---|
| `SIZE n` | Reject or bounce locally any message whose encoded size is > n, and declare `SIZE=` on MAIL |
| `PIPELINING` | Send MAIL, the RCPT commands and DATA in one write, and check every reply by count |
| `8BITMIME` | You may send `BODY=8BITMIME`. Otherwise, make sure the content uses quoted-printable (QP) or base64 encoding (never "just send 8-bit") |
| `CHUNKING` | You may use BDAT, but keep DATA as a fallback |
| `DSN` | Add ENVID and RET (and NOTIFY where appropriate), and expect bounces in the RFC 3464 format |
| `SMTPUTF8` | Recipients with internationalized addresses (EAI) can be delivered on this hop. See [SMTPUTF8 and EAI](https://emailmarketing.net/learn/rfc/smtputf8-eai) |
| `STARTTLS` | Negotiate TLS before sending mail (required by [MTA-STS](https://emailmarketing.net/learn/transport-security/mta-sts) policies) |

## Related articles

- [RFC 5321 — SMTP](https://emailmarketing.net/learn/rfc/rfc5321-smtp), the base protocol and its reply codes
- [Delivery Status Notifications (RFC 3464)](https://emailmarketing.net/learn/bounce-handling/delivery-status-notifications), the DSN format these parameters control
- [RFC 3834 — Auto-Replies](https://emailmarketing.net/learn/rfc/rfc3834-auto-replies), where `NOTIFY=NEVER` is recommended
- [MIME & Encoding](https://emailmarketing.net/learn/rfc/mime-and-encoding), on the encoding choices that SIZE, 8BITMIME and BINARYMIME interact with
