Email Deliverability

SMTP Error 503: What “Bad Sequence of Commands” Really Means and How to Fix It

Daniel Shnaider
13 min

TL;DR: SMTP 503 is defined by RFC 5321 as “Bad sequence of commands.” It means your client sent a command the server cannot accept in the current state of the session, almost always because a required earlier step was skipped, rejected, or repeated. It is a client-side protocol bug, not a reputation problem and not a blocklist. Read the text after the code, because that text names the exact step you missed. The two enhanced codes you will see are 503 5.5.1 (Postfix and most open-source MTAs) and 503 5.5.2 (Exchange and Exchange Online), and they point at the same class of fault.

What a SMTP Error 503 actually is

Every SMTP session is a state machine. The server tracks where you are: greeted or not, authenticated or not, transaction open or not, recipients accepted or not. Each command is legal only in certain states.

RFC 5321 assigns reply code 503 to exactly one condition: a command arrived that the server cannot process from its current state. The specification is blunt about it. If the commands in a transaction are out of order to the degree that the server cannot process them, a 503 failure reply must be returned, and the server must stay in the same state it was in before.

That last clause matters more than it looks. A 503 does not advance or reset anything. The session sits exactly where it was. Retrying the same command produces the same 503 forever, which is why 503 shows up in logs as a tight loop rather than a single failure.

Three things follow, and they cut against how this error is usually described.

  • It is not primarily an authentication error. Authentication is one trigger among several. The dedicated code for “you need to authenticate” is 530 5.7.0, defined in RFC 4954, not 503.
  • It is not a deliverability problem. Sender reputation, blocklists, SPF, DKIM, and DMARC have nothing to do with a 503. The server rejected your command before it ever evaluated your message. Warming up a domain will not fix a 503, and no reputation work will either.
  • It is permanent for that command, not for that message. The leading 5 makes it a permanent negative reply, so a retry queue will burn attempts pointlessly. Fix the sequence and the same message sends fine.

The sequence a server expects

RFC 5321 fixes the order. A session that will carry mail must be initialized with EHLO. The MAIL command opens a transaction. One or more RCPT commands follow. DATA comes last and is terminated by a line containing only a period.

Here is a complete submission session with authentication, which is what most senders are actually running. Client lines are marked C:, server lines S:.

  • S: 220 smtp.example.com ESMTP ready
  • C: EHLO mail.yourdomain.com
  • S: 250-smtp.example.com
  • S: 250-STARTTLS
  • S: 250-PIPELINING
  • S: 250 AUTH LOGIN PLAIN
  • C: STARTTLS
  • S: 220 2.0.0 Ready to start TLS
  • C: EHLO mail.yourdomain.com          <- required again after TLS
  • S: 250-smtp.example.com
  • S: 250 AUTH LOGIN PLAIN
  • C: AUTH LOGIN
  • S: 334 VXNlcm5hbWU6
  • C: [base64 username]
  • S: 334 UGFzc3dvcmQ6
  • C: [base64 password]
  • S: 235 2.7.0 Authentication successful
  • C: MAIL FROM:<you@yourdomain.com>
  • S: 250 2.1.0 Ok
  • C: RCPT TO:<them@example.com>
  • S: 250 2.1.5 Ok
  • C: DATA
  • S: 354 End data with <CR><LF>.<CR><LF>
  • C: [headers and body]
  • C: .
  • S: 250 2.0.0 Ok: queued as 4A1B2C3D
  • C: QUIT

Note the second EHLO. That single line is the most common cause of 503 in modern setups, and the next section explains why.

The rules that produce an SMTP Error 503, straight from the specs

Most guides describe 503 loosely. The standards are specific about when a server has no choice.

ConditionWhat the spec saysSource
RCPT arrives with no prior MAIL commandServer must return 503RFC 5321 §3.3
Commands out of order beyond what the server can processServer must return 503 and stay in the same stateRFC 5321 §4.1.4
DATA arrives with no MAIL, no RCPT, or all recipients rejectedServer may return 503 or 554RFC 5321 §3.3
A second AUTH after one already succeededServer must reject with 503RFC 4954 §4
AUTH issued during an open mail transactionServer must reject with 503RFC 4954 §4
Server opened with 554 instead of 220Intervening commands should get 503 until QUITRFC 5321 §3.1
NOOP, HELP, EXPN, VRFY, RSET before any EHLOServers should not return 503 for theseRFC 5321 §4.1.4

That last row is a useful diagnostic. If a server answers a bare NOOP with 503, it is behaving unusually strictly, and you are probably dealing with a hardened gateway or an appliance rather than a standard MTA.

Reading the enhanced status code (SMTP Error 503)

Modern servers append a three-part enhanced status code from RFC 3463. For the 503 family, the relevant values are:

  • 5.5.0 Other or undefined protocol status.
  • 5.5.1 Invalid command.
  • 5.5.2 Syntax error.
  • 5.5.4 Invalid command arguments.

Here is the practical part almost nobody publishes: the enhanced code tells you which software you are talking to more reliably than it tells you what you did wrong.

  • Postfix and most open-source MTAs use `503 5.5.1` for the entire sequencing family. Its published response strings include Error: send HELO/EHLO first, Error: need MAIL command, Error: need RCPT command, Error: nested MAIL command, Error: MAIL transaction in progress, Error: already authenticated, Error: authentication not enabled, and the BDAT variants DATA after BDAT, MAIL after BDAT, and RCPT after BDAT. Postfix also uses 503 5.5.4 Error: send AUTH command first and 503 5.5.4 Error: multiple AUTH= options.
  • Exchange and Exchange Online use `503 5.5.2` for the same conditions, with strings such as Send hello first and Need mail command. If your bounce shows 503 5.5.2 Send hello first alongside a hostname ending in protection.outlook.com, you are talking to Microsoft 365 and the greeting step is the fault.

So 5.5.1 and 5.5.2 are not two different problems. They are two vendors labeling the same state-machine rejection. Warmy has dedicated walkthroughs for each variant: 503 5.5.1 and 503 5.5.2.

7 causes worth checking, in order of how often they are the answer

1. STARTTLS without re-issuing EHLO

This is the top cause in current setups and the one most guides omit entirely.

RFC 3207 is explicit: once the TLS handshake completes, the SMTP protocol is reset to its initial state, the state right after the server’s 220 greeting. The server must discard everything it learned from the client before the handshake, including the EHLO argument. The client must discard the extension list it received, and should send EHLO again as its first command after TLS.

In other words, STARTTLS un-greets you. If your client sends EHLO, then STARTTLS, then goes straight to AUTH or MAIL FROM, the server sees a command from a client that has not introduced itself. Exchange Online answers 503 5.5.2 Send hello first. Postfix answers 503 5.5.1 Error: send HELO/EHLO first.

This breaks in a specific and maddening way: it works on plain connections and fails the moment you enable TLS, which sends people hunting for certificate problems that do not exist.

Fix: Send EHLO again immediately after the TLS handshake completes. Well-maintained libraries do this automatically. Hand-rolled socket code and older mail libraries frequently do not.

2. No EHLO or HELO at all

A client must issue HELO or EHLO before starting a mail transaction. Scripts that open a socket and go straight to MAIL FROM get a 503 on the first command.

A related trap: some clients send only HELO. Servers must still accept HELO, but a HELO session never receives the extension list, so the client never learns that AUTH or STARTTLS is available. What follows is usually an AUTH attempt the server refuses.

Fix: Send EHLO, and read the multiline 250 response before deciding what to do next.

3. AUTH sent at the wrong moment

RFC 4954 creates two hard SMTP 503 conditions around authentication, and both are easy to hit in code:

  • A second AUTH after one succeeded. Once authentication completes, no further AUTH commands may be issued in that session. A retry wrapper that re-authenticates on error will trip this. Postfix answers 503 5.5.1 Error: already authenticated.
  • AUTH during an open transaction. If you have already sent MAIL FROM, AUTH is illegal until the transaction ends or is reset.

A third variant is the reverse: sending MAIL FROM before AUTH on a submission port that requires it. Standards-compliant servers answer 530 5.7.0, but plenty of servers answer 503 with text like “Must authenticate first.”

Fix: Authenticate exactly once, after the post-TLS EHLO, and before MAIL FROM. On connection reuse, track auth state rather than re-running the login.

4. DATA with no accepted recipient

If every RCPT TO was rejected, the transaction has no recipients, and DATA cannot proceed. RFC 5321 permits the server to answer with either 503 or 554, which is why implementations differ: Postfix’s catalogue contains both 503 5.5.1 Error: need RCPT command and 554 5.5.1 Error: no valid recipients.

The important insight is that the 503 is a symptom. The real failure happened one step earlier, when your recipients were rejected for a bad address, relaying restrictions, or a policy block, and your code proceeded to DATA anyway.

Fix: Check the reply to every RCPT TO. Send DATA only if at least one returned 250. Log the RCPT rejections, because that is where the actual diagnosis lives.

5. A nested MAIL FROM on a reused connection

MAIL must not be sent while a transaction is already open. It may be sent only when no transaction has started, when the previous one concluded with a successful DATA, or when the previous one was aborted with RSET or a new EHLO.

Code that loops over a recipient list on one connection and forgets to reset between messages hits this immediately. Postfix returns 503 5.5.1 Error: nested MAIL command or Error: MAIL transaction in progress.

Fix: Send RSET between messages on a persistent connection. A fresh EHLO also clears state, though RSET is cheaper.

6. Pipelining without the extension

SMTP is deliberately lock-step, one command and one reply at a time, unless both sides agree to the PIPELINING extension (RFC 2920), which the server advertises in its EHLO response.

A client that writes EHLO, MAIL, RCPT, and DATA into the socket in one burst without confirming PIPELINING is announced can outrun the server’s state machine. Behavior varies by implementation, so this is not a guaranteed 503, but it is a real source of intermittent ones, and intermittency is the tell.

Fix: Check for 250-PIPELINING in the EHLO response before batching. If it is absent, wait for each reply.

7. Mixing BDAT with DATA

Servers that support CHUNKING accept BDAT instead of DATA. Mixing the two in one transaction is illegal, and Postfix names the condition precisely: DATA after BDAT, MAIL after BDAT, RCPT after BDAT.

Fix: Pick one transfer method per transaction. If your library added BDAT support in an update, that update is your suspect.

What SMTP Error 503 is not: A disambiguation table

Misreading a 503 as an authentication or blocklist problem wastes days. These are the codes it gets confused with.

CodeMeaningHow it differs from 503
500Syntax error, command unrecognizedThe verb itself was not understood
501Syntax error in parametersThe verb was fine, the argument was malformed
502Command not implementedThe command exists but the server does not offer it
530 5.7.0Authentication requiredThe correct code for “you have not logged in”
535 5.7.8Authentication failedYou logged in and the credentials were wrong
550 5.7.30Basic authentication not supported for Client SubmissionMicrosoft-specific, tied to the Basic Auth retirement
554No valid recipientsThe alternative reply for the DATA-with-no-RCPT case

If you are chasing 530 or 535 instead, Warmy has dedicated guides to SMTP error 530 and SMTP error 535 5.7.0.

Diagnosing it yourself in 5 minutes (SMTP 503)

Stop reading library stack traces and talk to the server directly. The transcript tells you the answer.

For a TLS submission endpoint on port 587:

  • openssl s_client -starttls smtp -crlf -connect smtp.example.com:587

For implicit TLS on port 465:

  • openssl s_client -crlf -connect smtp.example.com:465

Then type the sequence by hand, one command at a time, reading each reply before sending the next. For AUTH LOGIN you need base64 values, which you can generate separately:

  • echo -n ‘you@yourdomain.com’ | base64
  • echo -n ‘your-app-password’ | base64

Walk the full sequence: EHLO, AUTH, MAIL FROM, RCPT TO, DATA, body, a lone period, QUIT. Whichever command returns the 503 is your answer, and the text after the code names the missing step.

If you prefer one command over a manual session, swaks runs the whole transaction and prints both sides:

  • swaks –to them@example.com –from you@yourdomain.com \ –server smtp.example.com:587 –tls –auth

Two rules while testing. Use a real fully-qualified hostname in EHLO, not localhost, because some servers reject unqualified greetings outright. And run the manual session from the same host and network as your application, since a 503 that only appears from one machine usually means a proxy or security appliance is rewriting the conversation.

Fixes by environment

  • Custom scripts and libraries. A 503 from a maintained library (Python’s smtplib, Nodemailer, PHPMailer, the AWS and SendGrid SDKs) almost always means the sequence was hand-managed somewhere, or a persistent connection is being reused without RSET. Turn on the library’s debug output, capture the full transcript, and compare it against the annotated session above.
  • Google Workspace and Gmail. Use smtp.gmail.com, port 587 with STARTTLS or 465 with implicit TLS, and the full address as the username. Critically, your ordinary account password will not work. Google turned off access for apps using basic authentication on March 14, 2025, and SMTP with legacy passwords stopped functioning on that date. You need either OAuth or a 16-character App Password, and App Passwords require 2-Step Verification to be enabled on the account first. Any guide still telling you to enter your Gmail password is describing a setup that has not worked since 2025.
  • Microsoft 365 and Exchange Online. Use smtp.office365.com on port 587 with STARTTLS. The 503 5.5.2 Send hello first pattern here is nearly always the missing post-STARTTLS EHLO. Separately, plan for the authentication change: Microsoft’s January 2026 timeline has SMTP AUTH Basic Authentication behavior unchanged until December 2026, disabled by default for existing tenants at the end of December 2026, unavailable by default for new tenants after that, with a final removal date to be announced in the second half of 2027. When it is disabled, the failure is 550 5.7.30 Basic authentication is not supported for Client Submission, not a 503, so keep the two apart when you triage.
  • ESP relays. SendGrid, Amazon SES, Mailgun, and similar services accept the standard sequence but expect provider-specific credentials, not mailbox passwords. A 503 here usually means a hand-rolled client, since their SDKs handle sequencing for you.
  • On-premises servers and appliances. If you administer the receiving server, the logs name the offending command directly. Check whether a security gateway, antivirus proxy, or SMTP-aware firewall sits in front of it, because these devices sometimes strip or reorder commands and produce 503s that make no sense from the client’s perspective.

Preventing the next one

Most 503 errors are introduced by a change rather than discovered spontaneously, so the prevention list is short and specific.

Read every server reply instead of assuming success. Track session state explicitly rather than inferring it. Send RSET between messages on reused connections. Re-send EHLO after STARTTLS, always.

Check for advertised extensions before using them. Retry 4xx replies and never retry 5xx ones, because retrying a 503 is guaranteed to fail and can trip rate limits. And test after every dependency upgrade, since mail libraries change sequencing behavior between versions more often than you would expect.

Where sender reputation actually comes in

Warmy.io Warmup Performance Weekly Report

A 503 is a configuration bug, and no reputation service will fix it. It is worth being clear about that, because plenty of articles blur the line.

What reputation does determine is what happens after the fix. Once your commands are in the right order and your messages are being accepted, whether they reach the inbox depends on authentication and sending history. That is a separate problem with separate tools: correct SPF and DMARC records, a gradual email warm-up rather than an abrupt volume ramp, and monitoring so you learn about placement problems before your reply rate does.

Warmy’s free deliverability test reports per-provider inbox placement, blocklist status, and DNS record configuration, which is the right first check once the protocol side is working.

Summarize with AI
30-minute demo

Meet our Experts

Unlock the secrets to a strong domain reputation with our deliverability experts

Talk to an expert

Free consultation call

30 minutes

One of our experts will walk you through the platform and show you how Warmy can help your business