STARTTLS (mail, FTP, XMPP, databases, RDP)
Mail servers usually start in plaintext and upgrade with STARTTLS. pqdoctor does that exchange before every probe, then runs the same TLS checks.
pqdoctor smtp.example.com:587 # STARTTLS by portpqdoctor mail.example.com:143 # IMAPpqdoctor mail.example.com:2525 --starttls smtpBy port: 25 and 587 are SMTP, 143 is IMAP, and 110 is POP3. --starttls smtp|imap|pop3|none overrides that. The other protocols pqdoctor upgrades are below.
The stack comes from the server’s greeting (the SMTP 220, IMAP * OK or POP3 +OK line), so the fix is written for Postfix, Dovecot, Exim or Exchange. A server that doesn’t offer STARTTLS on the port gets an error, not a diagnosis.
The setting names come from each project’s docs. Check them against your version, and confirm with openssl s_client -starttls ….
Postfix
Section titled “Postfix”Postfix gets PQ from OpenSSL (postconf -a, openssl version). Its group list is tls_eecdh_auto_curves. Check the name and default in your release’s postconf(5).
# main.cftls_eecdh_auto_curves = X25519MLKEM768 X25519 prime256v1Dovecot
Section titled “Dovecot”Dovecot passes ssl_curve_list to OpenSSL as its group list. It needs OpenSSL 3.5 or newer underneath.
# dovecot.conf (2.3)ssl_curve_list = X25519MLKEM768:X25519:prime256v1Exim built against OpenSSL 3.5 or newer can take a group list in tls_eccurve. Check your version’s spec for list support.
tls_eccurve = X25519MLKEM768:X25519:prime256v1Exchange / Windows Schannel
Section titled “Exchange / Windows Schannel”PQ key exchange depends on the Windows Server version’s Schannel. Until it offers ML-KEM, put a PQ-capable mail relay in front, such as Postfix on OpenSSL 3.5.
Shown in the fix lab
Section titled “Shown in the fix lab”The lab’s mail servers greet like Postfix and Dovecot, do the SMTP, IMAP or POP3 STARTTLS exchange, then speak TLS on OpenSSL 3.5 with the given groups.
| Case | pqdoctor said | Fix applied | After |
|---|---|---|---|
SMTP STARTTLS, groups X25519:P-256 |
Not PQ (stack from the greeting: postfix) | Postfix list X25519MLKEM768:X25519:prime256v1 |
PQ |
IMAP STARTTLS, groups X25519 |
Not PQ (dovecot) | Dovecot list | PQ |
POP3 STARTTLS, groups P-256:P-384 |
Not PQ (dovecot) | Dovecot list | PQ |
| SMTP without STARTTLS | “the server doesn’t offer STARTTLS on this port” | — | — |
Postfix’s space-separated list was joined with colons, which is how Postfix hands it to OpenSSL. Postfix, Dovecot and Exim themselves weren’t run. Only their group strings went through OpenSSL 3.5.
FTP, XMPP, LDAP, databases and RDP
Section titled “FTP, XMPP, LDAP, databases and RDP”| Protocol | Port | --starttls |
The upgrade |
|---|---|---|---|
| FTP | 21 | ftp |
AUTH TLS (RFC 4217). The greeting names vsFTPd or ProFTPD |
| XMPP | 5222 | xmpp |
A client stream to the host name, then <starttls/> → <proceed/> (RFC 6120) |
| LDAP | 389 | ldap |
The StartTLS extended operation (RFC 4511 / 4513) |
| PostgreSQL | 5432 | postgres |
SSLRequest → S |
| MySQL / MariaDB | 3306 | mysql |
The server’s handshake must offer CLIENT_SSL; then an SSLRequest. The greeting gives the version |
| RDP | 3389 | rdp |
X.224 Connection Request with RDP_NEG_REQ (TLS or CredSSP); TLS follows. There’s no openssl s_client equivalent, so verify says so |
pqdoctor ftp.example.com:21pqdoctor xmpp.example.org:5222pqdoctor db.example.com:5432pqdoctor rdp.example.com:3389pqdoctor ldap.example.com:10389 --starttls ldapA server that refuses the upgrade (no AUTH TLS, no xmpp-tls feature, N to SSLRequest, no CLIENT_SSL, RDP security only) gets a clear error, exit status 2.
Checked live on 2026-10-15: smtp.gmail.com:587 (post-quantum), test.rebex.net:21 FTPS (no-mlkem), jabber.org:5222 (no-mlkem), and Ubuntu 24.04’s PostgreSQL 16 in WSL (pinned-nist: its default ssl_ecdh_curve is prime256v1, which openssl s_client -starttls postgres confirmed). LDAP, MySQL and RDP are tested against fake servers only.
PostgreSQL 16 and older set one curve with ssl_ecdh_curve; newer releases take a group list. Check your release’s docs for the name, and that its OpenSSL is 3.5+.