TLS is not offered on connection begin

Your question

I’m testing my instance and get no 250-STARTTLS offered.

V: 0.16.7

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.

on

The most common cause of 250-STARTTLS not being advertised is that no TLS certificate is configured or resolvable for that listener. Stalwart only advertises STARTTLS when it can actually perform a TLS handshake; if the listener has no valid certificate, the extension is silently omitted (and a tls.not-configured error event is logged).

Here are the things to check, in order:

  1. Certificate exists and is assigned. In the WebUI go to Settings › Network › Listeners, open your SMTP/submission listener, and confirm useTls is true (the default). Then check Settings › System Settings and confirm defaultCertificateId points to a valid certificate object.

  2. A certificate object actually has a cert+key loaded. In the WebUI go to Settings › Network › TLS (or the Certificates section) and verify the certificate is present and not expired. If you are using ACME/Let’s Encrypt, confirm the ACME order completed successfully.

  3. Implicit TLS confusion. If your listener has tlsImplicit: true, the connection is TLS from byte one and STARTTLS is intentionally not advertised in the EHLO response (it’s not needed). Port 465 should be tlsImplicit: true; port 587 and port 25 should be tlsImplicit: false (the default).

  4. Check server logs for tls.not-configured. The docs describe this event as: “A TLS connection was requested but no certificate is configured for this listener.” If you see this in the logs, the root cause is a missing or mis-assigned certificate.

Relevant docs:

This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.

STARTTLS is advertised only when two things are true: the connection is not already inside TLS, and the listener has TLS enabled with a usable certificate. So the most likely cause is that TLS is not enabled on the listener you are testing, or no certificate is configured for it, so the listener came up as plain.

The other common case is testing an implicit-TLS port (465 or 993): there the session is already encrypted, so STARTTLS is intentionally not offered, which is correct.

I found my solution, port 25 enable tls wasn’t activated. Now it’s offered on connection to port 25. Thanks!