SSL_accept error in your mail logs means the TLS handshake on an inbound connection failed mid-negotiation. The remote SMTP client connected, STARTTLS was offered, and the OpenSSL handshake aborted before a session was established. Postfix either rejects the message (mandatory TLS) or silently falls back to plaintext (opportunistic TLS).
Default Postfix does not log failed opportunistic TLS handshakes. Both smtpd_tls_loglevel and smtp_tls_loglevel default to 0. You see successful TLS connections but not the ones that failed and fell back to cleartext. You may be delivering mail in plaintext to destinations you believe require encryption, with the only visible symptom being a deferred queue growing with delivery delays.
Inbound failures produce SSL_accept error on your smtpd side. Outbound failures produce SSL_connect error or deferrals with TLS-related reason strings. These present differently and require different diagnostic paths.
What it means
A TLS handshake failure occurs when Postfix and the remote peer cannot agree on a compatible protocol version, cipher suite, or certificate chain. The failure is at the OpenSSL layer. Postfix delegates all TLS negotiation to OpenSSL and reports the outcome.
Three categories dominate production:
Inbound handshake failures (
SSL_accept error): A remote client connected to yoursmtpd, attempted STARTTLS, and the handshake failed. If your policy ismay(opportunistic), the client may retry without TLS and deliver in plaintext. If your policy isencryptorverify, the message is rejected.Outbound handshake failures (
SSL_connect erroror silent deferral): Yoursmtpclient attempted STARTTLS to a remote MX, the handshake failed, and Postfix either fell back to plaintext (opportunistic) or deferred the message (mandatory). Deferred failures show up in the deferred queue with TLS-related reason strings, not as explicit TLS errors.Unexpected
Anonymous TLS connection: Postfix logs this when it completes a TLS handshake without verifying the peer certificate. For opportunistic TLS to localhost (e.g., submission relayed tosmtpdon 127.0.0.1), this is normal. For outbound delivery to a partner MX where you expected certificate verification, it indicates a policy mismatch or a missingsmtp_tls_security_level = verify.
flowchart TD
A[TLS failure in logs] --> B{Inbound or outbound?}
B -->|SSL_accept error| C[smtpd: reject or fall back]
B -->|SSL_connect or deferred| D[smtp client: defer or fall back]
C --> E{TLS policy?}
D --> E
E -->|Mandatory encrypt/verify| F[Rejected or deferred: visible]
E -->|Opportunistic may| G[Silent plaintext fallback]
G --> H[Invisible at loglevel 0]Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Cipher suite mismatch | no shared cipher or SSL_accept error from specific clients only | postconf smtpd_tls_ciphers smtpd_tls_mandatory_ciphers |
| Protocol too restrictive | Clients fail after you set >=TLSv1.3 on a public MX | postconf smtpd_tls_mandatory_protocols smtpd_tls_protocols |
| Certificate problem | SSL_accept error with certificate verify failed or chain errors | Check cert expiry, chain completeness, key/cert file paths |
| ECDSA cert without RSA fallback | no shared cipher from RSA-only clients | Check if only smtpd_tls_eccert_file is set, no RSA cert |
| OpenSSL 3.x legacy sigalg | legacy sigalg disallowed or unsupported on outbound to TLS 1.0 servers | openssl version and target server TLS version |
| DPI or TLS interception | Handshake fails on one network path but succeeds from another | Compare openssl s_client from MTA vs. different network |
| Clock skew | Certificate validation fails intermittently, resolves on its own | chronyc tracking or ntpstat on the MTA |
| Deprecated TLS parameters | postconf warns about obsolete parameters after upgrade | postconf -n output for smtp_use_tls, smtpd_use_tls, etc. |
Quick checks
# Check current TLS log levels (default is 0: failed opportunistic TLS is invisible)
postconf -h smtpd_tls_loglevel smtp_tls_loglevel
# Check inbound TLS protocol and cipher configuration
postconf -h smtpd_tls_protocols smtpd_tls_mandatory_protocols smtpd_tls_ciphers smtpd_tls_mandatory_ciphers
# Check outbound TLS protocol and cipher configuration
postconf -h smtp_tls_protocols smtp_tls_mandatory_protocols smtp_tls_ciphers smtp_tls_mandatory_ciphers
# Check TLS security levels
postconf -h smtpd_tls_security_level smtp_tls_security_level
# Check for deprecated TLS parameters (Postfix 3.9+ warns on these)
postconf -n 2>&1 | grep -E 'smtp_use_tls|smtpd_use_tls|smtp_enforce_tls|smtpd_enforce_tls|smtp_tls_per_site'
# Count recent TLS handshake errors
# Path is /var/log/mail.log on Debian/Ubuntu, /var/log/maillog on RHEL/CentOS
grep -E 'SSL_accept error|SSL_connect error|TLS handshake failed' /var/log/mail.log | tail -20
# On systemd-only hosts without persistent syslog files:
# journalctl -u postfix -S '1 hour ago' | grep -E 'SSL_accept error|SSL_connect error'
# Check specifically for cipher mismatch errors
grep 'no shared cipher' /var/log/mail.log | tail -20
# Check for Anonymous TLS connections (may indicate unexpected opportunistic fallback)
grep 'Anonymous TLS connection' /var/log/mail.log | tail -20
# Test your own server's TLS handshake from localhost
openssl s_client -connect localhost:25 -starttls smtp </dev/null 2>&1 | head -20
# Test outbound TLS to a specific destination MX
openssl s_client -connect mx.example.com:25 -starttls smtp </dev/null 2>&1 | head -20
# Check OpenSSL version (relevant for legacy sigalg compatibility)
openssl version
How to diagnose
Raise TLS logging temporarily. Set
smtpd_tls_loglevel = 1andsmtp_tls_loglevel = 1, then reload. This reveals opportunistic TLS fallbacks and negotiation details without dumping hex. Level 2 logs each negotiation phase; level 3 dumps the full handshake. Do not leave level 2 or 3 in production. It is noisy and may expose sensitive negotiation data in logs.Determine inbound versus outbound. Search for
SSL_accept error(inbound, yoursmtpd) versusSSL_connect erroror TLS-related deferral strings (outbound, yoursmtpclient).For inbound
SSL_accept error, identify the failing clients. Extract client IPs and correlate with the error detail string. If failures come from a narrow set of IPs or specific providers (Gmail, Outlook, Earthlink), the problem is likely cipher or protocol compatibility. If failures are widespread, suspect your certificate chain or a globally restrictive policy.For outbound failures, check deferred queue reason strings. TLS-related outbound failures present as
status=deferredwith reason text mentioning TLS, SSL, or certificate verification, not as explicitSSL_connect error. Correlate deferred queue growth with TLS log entries.Reproduce the handshake with
openssl s_client. Use-starttls smtpfor SMTP. Add-tls1_2or-tls1_3to test specific protocol versions. Add-cipherto test TLS 1.2 and earlier cipher constraints, and-ciphersuitesfor TLS 1.3 suites. The output shows the negotiated protocol, cipher, and certificate chain, which narrows the problem immediately.Check for deprecated parameters. If the problem appeared after a Postfix upgrade, run
postconf -nand look for warnings. Postfix 3.9 madesmtp_use_tls,smtpd_use_tls,smtp_enforce_tls,smtpd_enforce_tls, andsmtp_tls_per_siteofficially obsolete. They still function but log warnings and may behave subtly differently. Replace withsmtp_tls_security_levelandsmtpd_tls_security_level.Check OpenSSL version compatibility. If Postfix is linked against OpenSSL 3.0.x and outbound deliveries to older servers fail with
legacy sigalg disallowed or unsupported, the remote server is negotiating TLS 1.0 with a legacy MD5+SHA1 composite signature that OpenSSL 3.x rejects by default.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
| TLS handshake error count | Direct measure of TLS interoperability failures | Any sustained rate for mandatory TLS; above 2-5% for opportunistic |
| Opportunistic TLS success ratio | Tracks silent plaintext fallbacks invisible at loglevel 0 | Ratio dropping below baseline after config change or upgrade |
| Deferred entries with TLS reason strings | Outbound TLS failures defer rather than error | Spike in deferrals containing TLS, SSL, or certificate keywords |
| Certificate expiration date | Expired certs cause immediate handshake failures for verified connections | Within 30 days of expiry |
| Postfix and OpenSSL versions | Version changes introduce compatibility breaks | Recent upgrade followed by new TLS errors |
Anonymous TLS connection frequency | May indicate unexpected opportunistic fallback on outbound | Spike to destinations where mandatory TLS was expected |
postconf warnings | Deprecated parameters may behave differently after upgrade | Any warning mentioning obsolete TLS parameters |
Fixes
Warning:
postconf -ewrites directly tomain.cfandpostfix reloadapplies changes immediately. Test on a staging server first if possible, and always verify withpostconf -nafter reloading.
Cipher suite mismatch
The most common inbound failure is a cipher mismatch between your server and connecting clients. Postfix defaults to medium grade ciphers (128-bit or better) for both smtpd_tls_ciphers and smtpd_tls_mandatory_ciphers.
If you tightened cipher policy and old clients now fail:
# Check current cipher policy
postconf -h smtpd_tls_ciphers smtpd_tls_mandatory_ciphers
# If you over-tightened, restore the default medium grade
postconf -e 'smtpd_tls_ciphers = medium'
postfix reload
Do not apply the Mozilla “Modern” TLS profile to a public MX host. Many legitimate mail servers still negotiate TLS 1.2 only. A >=TLSv1.3 mandatory protocol or a cipher list that excludes all TLS 1.2-compatible suites will reject legitimate mail from real providers.
ECDSA certificate without RSA fallback
If your server presents only an ECDSA certificate (smtpd_tls_eccert_file / smtpd_tls_eckey_file) and a connecting client supports only RSA ciphers, the handshake fails with no shared cipher. Postfix supports configuring both RSA and ECDSA certificates simultaneously. The negotiated cipher determines which certificate is presented.
# Check which certificate types are configured
postconf -h smtpd_tls_cert_file smtpd_tls_eccert_file
# If only ECDSA is set, add an RSA certificate as well
postconf -e 'smtpd_tls_cert_file = /etc/letsencrypt/live/example.com/fullchain.pem'
postconf -e 'smtpd_tls_key_file = /etc/letsencrypt/live/example.com/privkey.pem'
postfix reload
Protocol version too restrictive
Postfix 3.6+ uses the >=TLSv1.2 inclusion syntax for smtpd_tls_protocols and smtpd_tls_mandatory_protocols. Before 3.6, only the exclusion syntax (!SSLv2, !SSLv3, !TLSv1, !TLSv1.1) was available. SSLv2 and SSLv3 are disabled by default in all modern Postfix releases.
# Check current protocol policy
postconf -h smtpd_tls_protocols smtpd_tls_mandatory_protocols
# For a public MX, do not raise mandatory protocols above TLS 1.2
# >=TLSv1.3 will reject all TLS 1.2-only clients
TLS 1.3 and certificate-less operation
TLS 1.3 requires server certificates. If you operate a server without certificates, relying on anonymous ciphers (aNULL) only, TLS 1.3 negotiation will fail. To run certificate-less, you must explicitly disable TLS 1.3:
postconf -e 'smtpd_tls_protocols = <=TLSv1.2'
postfix reload
This is an unusual configuration. Most production servers should have certificates configured. Anonymous ciphers (aNULL) are enabled by default for opportunistic TLS on both server and client. They are automatically disabled when client certificates are requested (server side) or when server certificates are verified (client side).
OpenSSL 3.x legacy sigalg failure
When Postfix linked against OpenSSL 3.0.x connects to a server that negotiates TLS 1.0, the ServerKeyExchange may use a legacy MD5+SHA1 composite signature that OpenSSL 3.0 rejects. The resulting error is SSL routines::legacy sigalg disallowed or unsupported.
Options:
- Upgrade the remote server to TLS 1.2 or higher. Preferred, but you may not control the remote system.
- Lower the client security level by appending
@SECLEVEL=0to the cipher string. This weakens security for affected connections. Apply it only to specific destinations viasmtp_tls_policy_maps, not globally.
Clock skew
Certificate validation depends on correct system time. If the MTA clock is skewed, certificates may appear expired or not-yet-valid, causing handshake failures that resolve when time corrects.
# Check system clock synchronization
chronyc tracking 2>/dev/null || ntpstat 2>/dev/null || timedatectl status
Deprecated TLS parameters
Postfix 3.9 made several TLS parameters obsolete. They still function but log warnings and should be migrated:
| Obsolete parameter | Replacement |
|---|---|
smtp_use_tls = yes | smtp_tls_security_level = may |
smtpd_use_tls = yes | smtpd_tls_security_level = may |
smtp_enforce_tls = yes | smtp_tls_security_level = encrypt |
smtpd_enforce_tls = yes | smtpd_tls_security_level = encrypt |
smtp_tls_per_site | smtp_tls_policy_maps |
After migrating, run postfix reload and verify with postconf -n that no warnings remain.
TLS 1.3 cipher names have no effect in cipher strings
TLS 1.3 bulk encryption ciphers (such as TLS_AES_128_GCM_SHA256) are not part of the OpenSSL cipherlist mechanism. Listing them in smtp_tls_ciphers or smtpd_tls_ciphers has no effect on TLS 1.3 negotiation. If you believe you are constraining TLS 1.3 ciphers this way, you are not. TLS 1.3 cipher selection is controlled separately.
Prevention
Keep TLS log levels at 1 for at least the SMTP client side. Default level 0 hides failed opportunistic TLS entirely. You cannot detect silent plaintext fallbacks without at least level 1 logging. The log volume overhead is minimal.
Monitor TLS failure rates alongside deferred queue growth. Outbound TLS failures defer, they do not bounce. A growing deferred queue with TLS-related reason strings is the earliest visible signal of an outbound TLS problem.
Test after every Postfix or OpenSSL upgrade. Version changes introduce new protocol defaults, deprecate old parameters, and change cipher behavior. Run
openssl s_client -starttls smtpagainst your own server and against at least two major destination MX hosts after each upgrade.Track certificate expiration for both inbound and outbound TLS. Monitor the
smtpdcertificate and any client certificates used for mutual TLS to partner destinations. Outbound TLS failures from expired client certificates cause silent deferrals, not obvious errors.Avoid the Mozilla “Modern” profile on public MX hosts. Public mail servers need broad TLS 1.2 compatibility. The Modern profile is designed for HTTPS frontends with controlled client populations, not for SMTP where peer diversity is high and you cannot dictate client capabilities.
Run
postconf -nafter upgrades to catch deprecated parameters. Postfix logs warnings for obsolete parameters but does not remove them. Catch them before they cause subtle behavioral drift.
How Netdata helps
Correlate TLS error rates with deferred queue growth. A spike in
SSL_accept errororSSL_connect errorlog entries that coincides with deferred queue expansion confirms a TLS-related delivery problem, distinguishing it from a DNS or network issue. Per-second granularity makes the correlation precise.Detect silent plaintext fallbacks. By tracking the ratio of
Anonymous TLS connectionlog entries to total outbound deliveries over time, a drop in that ratio after a configuration change or upgrade signals that opportunistic TLS is failing and falling back to plaintext rather than producing visible errors.
Track certificate expiration proactively. Certificate expiry is a predictable, deterministic failure. Alerting on days-to-expiry for the
smtpdcertificate and any mutual-TLS client certificates prevents the most common TLS outage.Separate TLS failures from DNS and network failures. All three produce deferred mail and all three look similar in aggregate. Correlating TLS error log patterns with DNS resolver latency and SMTP connection timeout metrics isolates a cipher mismatch from a resolver outage or a network partition.
Monitor Postfix process health during TLS incidents. TLS negotiation is CPU-intensive. Elevated CPU on
smtpdorsmtpprocesses combined with rising TLS error rates may indicate resource contention or a computational workload spike, not just a cipher incompatibility.
Related guides
- Postfix active queue saturation: hitting qmgr_message_active_limit
- Postfix backscatter storm: bounces to forged senders and blocklisting
- Postfix IP blocklisted: deliverability collapse and sender reputation
- Postfix bounce rate spike: 5xx failures, bad address lists, and reputation risk
- postfix check warnings: configuration drift and permission problems
- Postfix Connection refused: blocked port 25 and rejected outbound delivery
- Postfix Connection timed out: delivery deferrals to unreachable destinations
- Postfix content_filter backpressure: incoming queue growth when Amavis or Rspamd slows
- Postfix deferred queue growing: why mail piles up and how to drain it
- Postfix destination concurrency limit: tuning per-destination delivery
- Postfix queue partition disk full: /var/spool/postfix out of space
- Postfix DNS resolver failure: when a broken resolver defers mail to everyone






