502 5.5.2 Error: command not recognized is Postfix's reply when your client sends something it
cannot parse as an SMTP command at all. It is a permanent 5xx, but it is a **client-side protocol
bug**: no recipient was evaluated, no content was read, and your sender reputation is not
involved. Fix the client and the message sends.
The code pairing is itself diagnostic. RFC 3463 pairs 502 with 5.5.1 ("invalid command") and
500 with 5.5.2 ("syntax error"). Postfix crosses them and sends 502 5.5.2, which means if
you are looking at that exact pair you are almost certainly talking to Postfix - useful, because
Postfix's behaviour here is well documented and deterministic.
The transcript
$ openssl s_client -starttls smtp -connect mx.example.com:25 -crlf 250-mx.example.com 250-PIPELINING 250-SIZE 10240000 250 8BITMIME VRFY test@mailpilots.in 502 5.5.1 VRFY command is disabled HELO 501 Syntax: HELO hostname MAIL FROM <sender@yourdomain.com> 502 5.5.2 Error: command not recognized
Look at the last two lines. MAIL FROM <addr> with no colon is not the MAIL FROM:<addr> the
grammar requires, so Postfix cannot identify the verb-plus-argument shape and answers 502 5.5.2
rather than a more specific syntax error. A single missing colon is a surprisingly common cause in
hand-written SMTP code.
The causes, in order
- Bare LF instead of CRLF. SMTP requires every line to end with
<CR><LF>. Code that writes
"\n" works against lenient servers and fails against strict ones, and the failure mode is
exactly this: the server reads the previous command plus your next line as one unrecognisable
blob. This is the first thing to check, always.
- A malformed command. A missing colon in
MAIL FROM:, a space before the colon, or angle
brackets omitted around the address.
- A command the server has switched off.
VRFY,EXPN,ETRNandHELPare commonly
disabled to prevent address harvesting. A library that probes with VRFY for address
verification will get 502 on most modern servers - and address verification by VRFY has not
been reliable for twenty years.
- Commands sent before reading the greeting. If your client writes
EHLObefore it has read
the 220, the server may read your bytes while still mid-greeting and reject them.
- A proxy or load balancer mangling the stream. SMTP-aware firewalls and TLS-terminating
proxies insert, strip or re-wrap lines. The signature is a client that works directly against
the server and fails through the appliance.
- Non-ASCII in a command. A UTF-8 address in
MAIL FROMwhen the server has not advertised
SMTPUTF8 is not a valid command. The address must be in punycode/ASCII form unless the
extension is offered.
- Raw data sent outside `DATA`. A client that starts writing the message body before the
server's 354 sends body lines where commands belong, and every one comes back 502.
502 5.5.2 against its neighbours
| Reply | Server's complaint | Fix |
|---|---|---|
500 5.5.2 | Syntax error in a line it tried to parse | Correct the command syntax |
502 5.5.1 | Valid command, not implemented or disabled here | Stop using that command |
502 5.5.2 | Could not identify this as a command at all | Check line endings first, then syntax |
503 5.5.1 | Valid, implemented command sent at the wrong time | Fix the command ordering |
The distinction between 502 5.5.1 and 502 5.5.2 is worth keeping straight: the first means
"I know what that is and I will not do it", the second means "that is not a command". The first
needs a change in which commands you use; the second needs a change in how you write them.
The ordered fix
- Check line endings. Confirm your client writes
\r\n, not\n. In a hex dump of the
session you should see 0d 0a at the end of every command line. This resolves the majority of
cases.
- Capture the session. Use
openssl s_client -crlfor your library's SMTP debug mode and
read the exact bytes of the command that was refused. The refused line is in the transcript
directly above the 502.
- Remove `VRFY` and `EXPN` from your flow. They are disabled nearly everywhere and were never
a dependable way to validate an address.
- Update the mail library. Line-ending and command-grammar bugs are long fixed in current
versions of every mainstream library; a pinned ancient dependency is a common source.
- Test directly against the server, bypassing any proxy. If it works, the appliance is the
cause and the fix is to stop it inspecting SMTP.
- Confirm `SMTPUTF8` before sending an internationalised address in a command. If the server
does not advertise it, convert the domain to punycode.
What not to do
- Do not retry the message unchanged. A
5xxon an unparseable command will fail identically
every time, and your queue will carry it until the retry timeout.
- Do not record a bounce or suppress the recipient. The failure happened in the SMTP
conversation. Marking the address is recording a code defect as a list-quality problem.
- Do not treat it as a deliverability or reputation issue. The receiving server never saw a
message, so it formed no opinion of you. Nothing here needs warming up or delisting.
- Do not write a retry loop that reconnects on `502`. Rapid reconnection after malformed
commands is indistinguishable from a port scan, and some hosts will start refusing your IP at
connection time.
- Do not work around a disabled `VRFY` by sending a real message to test an address. That is a
send to an unverified address, which is exactly what harms your bounce rate.
MailPilot avoids this class entirely for Gmail and Outlook by using OAuth and the provider APIs
rather than hand-rolled SMTP, and for SendGrid, Amazon SES, Mailgun, Postmark and custom servers
it completes a full validated session when you connect the mailbox - so a protocol fault shows up
at setup, not as a warm-up that quietly never sends.
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