New articles: - Postfix SendGrid TLS handshake failure (port 465 vs 587) - Plex transcoding troubleshooting - Ansible Ubuntu reboot detection kernel mismatch - WSL2 PyTorch checkpoint Windows filesystem deadlock Updated: - AWS S3 cost management (expanded) - Network overview (IP updates) - HEVC VAAPI batch encode (progress + fixes) - SUMMARY.md (new entries)
2.8 KiB
Postfix + SendGrid: TLS Handshake Failure (Port 465 vs 587)
Symptom
Outbound mail silently queues with no delivery. postqueue -p shows deferred messages:
(Cannot start TLS: handshake failure)
/var/log/maillog shows:
SSL_connect error to smtp.sendgrid.net[...]:465: -1
warning: TLS library problem: error:0A00010B:SSL routines::wrong version number
Or on port 587:
warning: TLS library problem: error:0A0000C1:SSL routines::no shared cipher
Root Cause
Port 465 (SMTPS) uses implicit TLS — the connection starts encrypted immediately. Port 587 (submission) uses STARTTLS — the connection starts plaintext, then upgrades.
Postfix has two settings that must match the port:
| Port | smtp_tls_wrappermode |
smtp_tls_security_level |
|---|---|---|
| 465 | yes |
encrypt |
| 587 | no |
encrypt (or may) |
If smtp_tls_wrappermode=yes is set with port 587, Postfix sends a TLS ClientHello immediately but the server expects a plaintext SMTP greeting first — wrong version number.
If smtp_tls_wrappermode=no is set with port 465, Postfix sends a plaintext EHLO but the server expects a TLS ClientHello — no shared cipher or connection reset.
Fix
Use port 587 + STARTTLS (recommended — more widely supported and debuggable):
postconf -e 'relayhost = [smtp.sendgrid.net]:587'
postconf -e 'smtp_tls_wrappermode = no'
postconf -e 'smtp_tls_security_level = encrypt'
systemctl restart postfix
postqueue -f # flush stuck messages
Verify
# Check config
postconf relayhost smtp_tls_wrappermode smtp_tls_security_level
# Test TLS connection manually
openssl s_client -starttls smtp -connect smtp.sendgrid.net:587 -brief
# Watch delivery
tail -f /var/log/maillog | grep status=
Successful delivery looks like:
Untrusted TLS connection established to smtp.sendgrid.net[...]:587: TLSv1.3 with cipher TLS_AES_128_GCM_SHA256
status=sent (250 Ok: queued as ...)
Why "Untrusted"?
If smtp_tls_CAfile and smtp_tls_CApath are both empty, Postfix can't verify the server certificate and logs "Untrusted TLS connection." The connection is still encrypted — just not authenticated. To fix, point to the system CA bundle:
postconf -e 'smtp_tls_CAfile = /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem' # Fedora
# or
postconf -e 'smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt' # Ubuntu/Debian
Notes
- OpenSSL 3.x is stricter about protocol mismatches than OpenSSL 1.1 — a config that worked on older distros may break after an OS upgrade.
- SendGrid supports both ports, but port 587 + STARTTLS is the documented recommendation.
- This applies to any SMTP relay (Mailgun, AWS SES, etc.), not just SendGrid — the port/wrappermode pairing is universal.