Prompt
How do I debug SMTP failures?
Latest observation
Debugging SMTP failures is mostly about narrowing down where the failure happens:
- DNS / connection
- TLS / authentication
- Message acceptance by the server
- Delivery / spam filtering after acceptance
Here’s a practical checklist.
1) Capture the exact error
Look for:
- SMTP status codes:
4xx= temporary failure,5xx= permanent failure - The server’s full response text
- Whether the failure happens at:
- connect
EHLOSTARTTLSAUTHMAIL FROMRCPT TODATA- final
.acceptance
Examples:
535 Authentication failed→ bad credentials, auth method, or account policy550 Relay denied→ server won’t send for that sender/recipient421/ timeout → server unreachable or blocked554 message rejected→ content/spam policy
2) Test basic connectivity
From the same host/app machine:
nc -vz smtp.example.com 587
or
telnet smtp.example.com 25
If port 587/465/25 doesn’t connect:
- firewall/security group issue
- wrong hostname
- ISP/provider blocking outbound SMTP
- server down
3) Inspect the SMTP conversation directly
Use openssl s_client for TLS ports:
openssl s_client -starttls smtp -connect smtp.example.com:587
Then type:
EHLO test.example.com
This tells you:
- whether TLS works
- what SMTP extensions the server advertises
- whether the certificate is valid
For implicit TLS (usually 465):
openssl s_client -connect smtp.example.com:465
4) Verify authentication
Common auth problems:
- wrong username/password
- account requires app password / OAuth
- SMTP AUTH disabled on the account
- server requires
STARTTLSbefore AUTH - using the wrong port for the auth mode
Check what the server advertises after EHLO:
AUTH LOGINAUTH PLAINSTARTTLS
If your app tries AUTH before STARTTLS, many servers reject it.
5) Confirm sender and recipient policy
A server may reject messages because of:
MAIL FROMnot allowed- sender domain not permitted
- recipient domain blocked
- relay restrictions
- SPF/DKIM/DMARC alignment issues
- exceeding rate limits
Try a simple test message with:
- plain text body
- one recipient
- no attachments
- a known-good sender
6) Check headers and content
If the message is accepted but not delivered, inspect:
- spam score
- malformed headers
- invalid
From,Reply-To,Date - suspicious links or attachments
- missing
Message-ID
Send a minimal email first, then add complexity.
7) Look at server logs
If you control the SMTP server, logs are often the fastest path:
- Postfix:
/var/log/mail.log,/var/log/maillog - Exim: main log
- Exchange: message tracking / protocol logs
- SES/SendGrid/Mailgun: provider event logs
Search for:
- connection rejection
- auth failure
- TLS handshake errors
- policy checks
- queue/defer messages
8) Distinguish “accepted” vs “delivered”
SMTP success only means the server accepted the message, not that it reached inbox.
If accepted but missing:
- check spam/junk folder
- check DMARC/SPF/DKIM
- verify IP/domain reputation
- look for provider suppression lists
- inspect bounce logs or feedback loops
9) Use a client with verbose logging
Depending on your stack, enable debug output:
- Python smtplib:
smtp.set_debuglevel(1) - JavaMail:
mail.debug=true - Node / Nodemailer:
debug: true, logger: true - Postfix/Exim: server logs
- curl is not for SMTP, but can help with related network checks
This often shows exactly which SMTP command failed.
10) Common failure patterns
535 Authentication failed
- bad password
- app password required
- AUTH disabled
- TLS required first
530 Must issue STARTTLS first
- connect with TLS before AUTH
550 Relay denied
- server only relays for authenticated users
- sender/recipient not permitted
554 Transaction failed
- spam/content rejection
- policy violation
- invalid envelope/from address
421 Service not available
- temporary outage
- rate limit
- IP blocked
Timeouts / hangs
- firewall
- DNS issue
- TLS negotiation issue
- packet inspection / proxy interference
11) A simple step-by-step test
Try this from the same machine as your app:
openssl s_client -starttls smtp -connect smtp.example.com:587
Then manually:
EHLO test.example.com
AUTH LOGIN
If you get prompted for credentials, authentication is available. Then test:
MAIL FROM:<you@example.com>
RCPT TO:<target@example.com>
DATA
Subject: Test
Hello
.
QUIT
Where it fails tells you the problem stage.
12) If you want faster diagnosis, send these details
I can help interpret the failure if you provide:
- SMTP server hostname and port
- client language/library
- exact error message or SMTP code
- whether TLS/auth is used
- whether you control the server or use a provider
- the step that fails
If you want, paste the error and I’ll help pinpoint the likely cause.