503 Bad sequence of commands means your client sent a command the server was not ready to
accept at that moment. It is a protocol error in the SMTP conversation, which makes it one of the
few mail errors with no deliverability dimension at all: the recipient is irrelevant, your content
was never read, and your sender reputation is untouched. A library, a plugin, or a proxy broke the
sequence.
It is a 5xx, so the server will not accept a retry of the same broken sequence - but the message
itself is perfectly sendable once the client is fixed.
The sequence the server expects
S: 220 mx.example.com ESMTP Postfix C: EHLO client.yourdomain.com S: 250-mx.example.com S: 250-STARTTLS S: 250 AUTH PLAIN LOGIN C: STARTTLS S: 220 2.0.0 Ready to start TLS --- TLS handshake; all prior session state is discarded --- C: EHLO client.yourdomain.com <-- mandatory second EHLO S: 250 ... C: AUTH PLAIN ... S: 235 2.7.0 Authentication successful C: MAIL FROM:<sender@yourdomain.com> S: 250 2.1.0 Ok C: RCPT TO:<test@mailpilots.in> S: 250 2.1.5 Ok C: DATA S: 354 End data with <CR><LF>.<CR><LF>
The ordering rules come from RFC 5321 and RFC 3207. The one that catches the most implementations
is RFC 3207's requirement that after a successful STARTTLS, the client must discard all
knowledge from the previous EHLO and issue a new one. A server that follows the spec treats the
session as freshly greeted, so anything that assumes the earlier capability list is now wrong.
The seven causes
- `STARTTLS` without re-issuing `EHLO`. The client negotiates TLS, then jumps straight to
AUTH or MAIL FROM using capabilities it learned before the handshake. The server has reset
its state and answers 503. This is the most common cause in hand-rolled SMTP code.
- No `EHLO` or `HELO` at all. Some scripts open a socket and send
MAIL FROMimmediately.
Postfix replies 503 5.5.1 Error: send HELO/EHLO first.
- `AUTH` at the wrong moment. Once
MAIL FROMhas been accepted a mail transaction is in
progress and AUTH is no longer legal: 503 5.5.1 Error: MAIL transaction in progress.
- `DATA` with no accepted recipient. If every
RCPT TOwas rejected and the client sends
DATA anyway, the server answers 503 5.5.1 Error: need RCPT command. Clients that ignore
RCPT responses in a loop produce this constantly, and the real failure is in the RCPT
replies they discarded.
- A nested `MAIL FROM` on a reused connection. After
DATAcompletes, the client must send
RSET or begin a new transaction cleanly. Issuing a second MAIL FROM mid-transaction gives
503 5.5.1 Error: nested MAIL command.
- Pipelining without the extension. The client writes several commands in one packet without
waiting for replies, but the server never advertised PIPELINING. Responses go out of step and
the server rejects whatever arrives at the wrong moment.
- Mixing `BDAT` and `DATA`. The CHUNKING extension's
BDATand classicDATAcannot be
combined in one transaction. A client that supports both and switches mid-stream gets 503.
What 503 is not
| Code | Means | Not the same as 503 |
|---|---|---|
500 5.5.2 | Syntax error - the server could not parse the line | 503's command was valid, just early |
502 5.5.1 | Command recognised but not implemented | 503's command *is* implemented |
530 5.7.0 | Authentication required | A policy refusal, not an ordering error |
554 5.5.1 | No valid recipients, transaction refused outright | A rejection of the transaction, not of ordering |
Diagnose it in five minutes
Reproduce the session by hand. Anything your library does, you can do faster with openssl:
$ openssl s_client -starttls smtp -connect smtp.example.com:587 -crlf 250-smtp.example.com 250-PIPELINING 250-AUTH PLAIN LOGIN MAIL FROM:<sender@yourdomain.com> 503 5.5.1 Error: send HELO/EHLO first
There it is - openssl performed the STARTTLS handshake for you but did not send the second
EHLO, exactly as a buggy client would not. Type EHLO client.yourdomain.com and the same `MAIL
FROM` now succeeds. If your library fails where the manual session succeeds, the difference
between the two transcripts is your bug.
For a library you cannot easily instrument, turn on its SMTP debug logging - SMTPDebug = 2 in
PHPMailer, debug: true in Nodemailer - and compare the command order against the transcript
above line by line.
The ordered fix
- Capture the full command transcript. Without it you are guessing which of the seven.
- Confirm a second `EHLO` follows `STARTTLS`. If it is missing, that is the bug; stop here.
- Check that `RCPT TO` replies are being read. A client that ignores them will hit cause four
on every message with one bad address.
- Update the mail library. Causes one, six and seven are long-fixed bugs in current versions
of every mainstream library.
- Remove SMTP inspection from intermediate firewalls. Appliances that proxy SMTP can strip
capabilities or reorder commands and create a 503 in a client that is behaving correctly.
- Disable pipelining in the client if the server does not advertise it, rather than hoping.
What not to do
- Do not retry the message unchanged. The sequence will break identically.
- Do not suppress the recipient or record a bounce. The recipient was either never named or
already rejected for a separate reason you should be reading instead.
- Do not take this as a reputation signal. No receiving provider evaluated your mail.
- Do not work around cause four by sending to a single recipient per connection without fixing
the RCPT handling. You will hide the error and keep sending to dead addresses.
- Do not disable TLS to avoid the `STARTTLS` ordering rule. The rule is three lines of code;
plaintext submission is a permanent downgrade.
MailPilot sidesteps this category for Gmail and Outlook by connecting over OAuth rather than raw
SMTP, and for SendGrid, Amazon SES, Mailgun, Postmark and custom servers it validates the full
session - greeting, TLS, authentication, one real send - when the mailbox is added, so a protocol
fault appears at setup rather than silently stalling a warm-up ramp.
Ready to reach the inbox every time?
Automated email warmup across real peer mailboxes. Live inbox placement monitoring. Free 7-day trial - no credit card required.
Start free trial