I am unable to get email to deliver to Rackspace’s email; it fails with a TLS Handshake error. I’ve tried disabiling TLS in the default TLS policy, but it still attempts a TLS Handshake.
I realize this is probably due to old cyphers on the part of Rackspace, but calling up Rackspace and asking them to upgrade the cipher suite because I’m using Stalwart is going to go nowhere, and it isn’t optional that I get the mail delivered there.
Is there a fix I am missing?
Reproduction Steps
Send email to Rackspace.
Watch it fail with a TLS Handshake error.
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
PostgreSQL
Blob Storage
PostgreSQL
Search Engine
PostgreSQL
Directory Backend
Internal
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
This is exactly the scenario the docs describe. Since your handshake is failing on the TLS negotiation itself (old/incompatible cipher suites), setting startTls: "disable" won’t help because that only skips STARTTLS, not the handshake failure retry path. What you need is to select an MtaTlsStrategy where startTls is set to disableand have it actually be selected on retry after a TLS failure, or use allowInvalidCerts: true if the failure is really a certificate/cipher validation issue rather than “no cipher overlap” (rustls will refuse to negotiate obsolete ciphers no matter what allowInvalidCerts says, since that setting only relaxes certificate validation, not cipher/protocol support).
Given rustls deliberately excludes broken protocols/ciphers (SSL1/2/3, TLS 1.0/1.1, RC4, DES, 3DES, etc.), if Rackspace’s mail servers only offer those, no TLS strategy setting will make rustls negotiate them — the only workaround is to fall back to plaintext delivery for that specific destination via a retry-based strategy switch, exactly as shown in the docs example: define default, invalid-tls, and disable-tls MtaTlsStrategy objects, and use an MtaOutboundStrategy TLS expression that switches to disable-tls (which sets startTls: "disable") after a TLS failure on retry:
Simply setting startTls to disable on the strategy actually selected for the first attempt should stop Stalwart from even offering STARTTLS on that connection — if it’s still attempting a handshake despite that, check that the strategy with startTls: disable is actually the one being selected for delivery to Rackspace’s MX (via the TLS expression on MtaOutboundStrategy), since a mismatch there (e.g. still hitting the default strategy) would explain the handshake still occurring.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.