SMTP TLS rejection

Symptom:

SMTP Error: Could not connect to SMTP host. Connection failed.
stream_socket_enable_crypto(): SSL operation failed with code 1.
OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed

That message means the TLS handshake started and PHP/OpenSSL refused the server's certificate — not a Drupal-module bug. Symfony Mailer and the SMTP module both fail identically because the failure is in the trust/connection layer, below Drupal. Diagnose from the shell down, in priority order.

1. Sanity checks

  • Use a hostname, not an IP — the cert CN/SAN matches the hostname, not the address.
  • Port ↔ mode match: 587 → STARTTLS (explicit), 465 → SSL/TLS (implicit).
  • System clock — skew fails cert validity-window checks:
    ntpdate pool.ntp.org

2. Verify the cert chain from the shell

# STARTTLS on 587
openssl s_client -starttls smtp -connect smtp.example.com:587 \
  -servername smtp.example.com \
  -CAfile /etc/ssl/certs/ca-certificates.crt -showcerts </dev/null | \
  sed -n '/Server certificate/,/subject=/p; /Verify return code/p'

# Implicit TLS on 465
openssl s_client -connect smtp.example.com:465 \
  -servername smtp.example.com \
  -CAfile /etc/ssl/certs/ca-certificates.crt -showcerts </dev/null | \
  sed -n '/Server certificate/,/subject=/p; /Verify return code/p'

You want Verify return code: 0 (ok). Anything else is the root cause:

  • "Unable to get local issuer certificate" → missing intermediate.
  • "Certificate has expired" → provider must renew.
  • "Hostname mismatch" → wrong hostname.

3. Check PHP's CA bundle

/opt/php83/bin/php -i | egrep -i 'openssl|default_socket|openssl\.cafile|openssl\.capath|curl\.cainfo'

openssl.cafile should be empty or /etc/ssl/certs/ca-certificates.crt; openssl.capath usually /etc/ssl/certs. If they point at non-existent paths, refresh the trust store:

apt-get update
apt-get --reinstall install ca-certificates
update-ca-certificates

4. Test with swaks

apt-get install swaks
swaks --server smtp.example.com --port 587 --tls --tls-verify --protocol ESMTP
swaks --server smtp.example.com --port 465 --tls --tls-verify --protocol ESMTP

If swaks fails the same way, the problem is the TLS/CA/hostname layer, not Drupal.

5. TLS version + cipher (OpenSSL 3 vs. old servers)

openssl s_client -starttls smtp -connect smtp.example.com:587 \
  -servername smtp.example.com -cipher 'DEFAULT:@SECLEVEL=1' </dev/null | \
  egrep -i 'Protocol|Cipher|Verify return code'

If lowering to @SECLEVEL=1 makes it work, the SMTP server is too old. Do not make this permanent — push the provider to update TLS.

6. Module settings

/admin/config/system/smtp: match encryption to port (TLS for 587, SSL for 465); do not enable "allow self-signed" unless you run a private CA. For an enterprise/private CA, install the root and point the module's CA file at the system bundle:

mkdir -p /usr/local/share/ca-certificates/custom
cp /path/to/provider-root.crt /usr/local/share/ca-certificates/custom/provider.crt
update-ca-certificates
# Then set the module "CA file" to /etc/ssl/certs/ca-certificates.crt

7. Hostname + SNI

Always pass -servername hostname to openssl s_client to exercise SNI. If you connect by IP (or override via /etc/hosts) and the mailer passes the IP as the peer name, SNI verification fails.

8. IPv6 edge case

If DNS for the SMTP host has AAAA and the IPv6 path produces verification errors while IPv4 does not, pin IPv4:

openssl s_client -starttls smtp -connect smtp.example.com:587 \
  -servername smtp.example.com -4 \
  -CAfile /etc/ssl/certs/ca-certificates.crt </dev/null

BOA disables IPv6 by default, so this is rarely a concern on a stock host — but check whether a local mailer config bypasses that disable.

9. Full chain dump

openssl s_client -starttls smtp -connect smtp.example.com:587 \
  -servername smtp.example.com \
  -CAfile /etc/ssl/certs/ca-certificates.crt -showcerts </dev/null | \
  sed -n '/Certificate chain/,$p'

Inspect the chain manually against what your CA expects.

Error → fix quick table

openssl s_client says Fix
"Unable to get local issuer certificate" Missing intermediate; apt-get --reinstall install ca-certificates
"Certificate has expired" Provider must renew
"Hostname mismatch" Use the correct hostname, not an IP
Legacy cipher works only with @SECLEVEL=1 Server too old; push provider to update

Aegir's own outbound mail

For BOA's host-level mail (notifications, install/upgrade emails), the relay is set via _SMTP_RELAY_HOST in /root/.barracuda.cnf (default empty; the value is lower-cased and stripped of non-host characters before use). The smtpgapps helper installs and configures msmtp for a relay account. See Mailing policy for the relay setup and recommended ESP configuration.

Related

  • Mailing policy — BOA mail policy, _SMTP_RELAY_HOST, and the smtpgapps/msmtp setup.
  • SSL operations — the web-facing TLS chain (distinct from SMTP, same trust-store concepts).