What Is STARTTLS?

STARTTLS turns a plain-text connection into an encrypted one without changing ports. It is how most email is encrypted in transit today — and understanding its one structural weakness explains every policy layer built on top of it.


STARTTLS is a command, not a protocol. It lets a connection that began in plain text upgrade itself to TLS partway through, on the same port, without either side knowing in advance that encryption was available. That design is what got most of the internet's email encrypted — and its one structural weakness is why MTA-STS, DANE and TLS-RPT all exist.

The Problem STARTTLS Solved

The obvious way to encrypt a protocol is to give it a second port where TLS starts immediately — https alongside http, port 465 alongside port 25. That is implicit TLS, and it works, but it requires every server, firewall and client to agree on a new port before anything can move.

STARTTLS took the other route. Keep the existing port, keep the existing plain-text handshake, and add one command that says "switch to TLS now". A server that understands it upgrades; a server that does not carries on in plain text. That backwards compatibility is why SMTP could be encrypted incrementally across millions of independently operated servers — and it is also the reason encryption is optional by default.

STARTTLS is not specific to emailThe same upgrade pattern appears in IMAP (STARTTLS), POP3 (STLS), XMPP, LDAP and FTP (AUTH TLS). The mechanics and the trade-offs are identical everywhere: one port, an optional upgrade, and a plain-text window before it happens.

How the Upgrade Works

The sequence is short. The client greets the server, reads the capability list, asks for the upgrade, and then starts the conversation over — because everything said before the handshake is untrusted and must be discarded.

text
S: 220 mail.example.com ESMTP ready C: EHLO client.example.org S: 250-mail.example.com S: 250-STARTTLS <-- the offer S: 250-SIZE 35882577 S: 250 8BITMIME C: STARTTLS S: 220 2.0.0 Ready to start TLS ... TLS handshake: certificate, cipher, key exchange ... C: EHLO client.example.org <-- repeat, inside TLS S: 250-mail.example.com S: 250-AUTH PLAIN LOGIN <-- capabilities may differ now S: 250 8BITMIME

Two details in that exchange matter more than they look:

  • The second EHLO is mandatory. The first capability list arrived in plain text and could have been tampered with, so the client throws it away and asks again over the encrypted channel. This is also why AUTH commonly appears only in the second list — servers refuse to advertise authentication until the connection is protected.
  • The offer itself is unauthenticated. The 250-STARTTLS line is sent before any certificate has been presented. Nothing about it is signed, and nothing proves it was not removed in transit.

Opportunistic by Default

On the server-to-server transport leg, STARTTLS is opportunistic: senders use it when it is offered and fall back to plain text when it is not. That is a deliberate choice — refusing to deliver to a server without TLS would have meant losing mail during the decade it took for adoption to become universal.

The consequence is that three quite different outcomes all look like "delivered":

SituationWhat happensMessage protected?
Server offers STARTTLS, handshake succeedsSession encryptedYes, for this hop
Server does not offer STARTTLSSender delivers in cleartextNo
Offer present, handshake failsMost senders retry without TLSNo
Offer stripped in transitSender never knew it was availableNo, and nobody is told
Certificate invalid or self-signedUsually accepted anyway on port 25Encrypted, but unauthenticated

That last row is worth sitting with. On the transport leg most senders do not verify the certificate at all, because a strict check would reject a large share of legitimate mail servers. Opportunistic STARTTLS therefore protects against a passive observer recording traffic, and not against an active attacker who can modify it.

STARTTLS Stripping

The attack follows directly from the design. An attacker positioned between two servers watches the plain-text capability list go past and deletes or corrupts the 250-STARTTLS line — often by rewriting it to something the client will ignore, such as 250-XXXXXXXA, which keeps the line length identical and avoids breaking the session.

The sending server reads the modified list, concludes that TLS is unavailable, and delivers the message in the clear. No error is raised on either end. Nothing in the logs distinguishes it from a legitimate server that genuinely does not support TLS.

A stripped session looks exactly like a successful oneBoth ends report a normal delivery. The only signal is statistical — a sudden drop in the share of your inbound or outbound mail that was encrypted — which is precisely what TLS-RPT reporting was designed to surface.

Closing the Gap

You cannot fix stripping inside STARTTLS itself, because the vulnerable moment happens before any trust has been established. Every solution therefore works the same way: publish a commitment out-of-band, so a sender knows TLS should have been available and can refuse to fall back.

MechanismPublished asWhat it guarantees
MTA-STSA DNS TXT record plus an HTTPS-hosted policy fileSenders must use TLS with a valid, matching certificate
DANE (DNSSEC + TLSA)A signed TLSA record in DNSPins the exact certificate or key the server must present
TLS-RPTA DNS TXT record naming a reporting addressNothing on its own — it tells you when TLS failed
Implicit TLS (port 465)Nothing; the port implies itNo plain-text phase exists to strip

MTA-STS and DANE solve the same problem with different trust anchors: MTA-STS leans on the web PKI and HTTPS, DANE leans on DNSSEC. Publishing either one moves your domain from "encrypted when convenient" to "encrypted or not delivered". TLS-RPT is the companion to both — it is how you find out that a sender could not comply, instead of discovering it months later.

STARTTLS Versus Implicit TLS

For client submission the choice is straightforward, and the encryption you end up with is the same either way. What differs is whether a plain-text phase exists at all.

STARTTLSImplicit TLS
Typical port587 (submission), 25 (transport)465
Connection startsPlain text, upgraded on requestEncrypted from the first byte
DowngradableYes, by an active attackerNo — there is no offer to remove
Fails when misconfiguredFalls back silently, or hangsConnection refused or handshake error
CompatibilityUniversalUniversal for submission; rare for transport
The classic misconfigurationPairing the wrong mode with the port produces a hang rather than an error: each side waits for the other to speak first. Implicit TLS on 587 and STARTTLS on 465 are the two shapes of this, and they surface as a timeout that looks like a firewall problem. SMTP timeouts covers how to tell them apart.

Checking It Yourself

Everything above is observable from a terminal. Start with the capability list, then confirm the handshake actually completes and the certificate verifies:

bash
# Is STARTTLS advertised on the transport port? openssl s_client -connect mail.example.com:25 -starttls smtp -crlf </dev/null 2>&1 \ | grep -i 'starttls\|verify return' # Submission port, with the certificate chain and verify result openssl s_client -connect smtp.example.com:587 -starttls smtp -crlf </dev/null # Implicit TLS — encrypted before the banner arrives openssl s_client -connect smtp.example.com:465 -crlf </dev/null # Which hosts accept mail for the domain, in preference order dig +short MX example.com

Read Verify return code: 0 (ok) as a clean chain. Anything else names the problem — 10 is an expired certificate, 18 a self-signed one, 21 a chain that could not be verified. On port 25 those are often tolerated by real senders; on 587 they will stop clients from connecting.

Common Misconceptions

  • "STARTTLS is an older, weaker form of TLS." It is not a version of TLS at all — it is the command that starts one. The cipher suites and protocol versions are whatever the two ends negotiate.
  • "Port 465 is deprecated." It was briefly, in the late 1990s, and was formally reinstated for message submission in 2018. Both 465 and 587 are current.
  • "My mail is encrypted, so it is private." Only in transit, and only per hop. Every server along the path holds the message in plain text.
  • "The server advertises STARTTLS, so TLS is working." The offer and a successful handshake are different things. Certificates expire; ciphers stop overlapping.
  • "Enabling STARTTLS is enough." Without MTA-STS or DANE it stays optional, and an attacker can remove the option.
See the TLS upgrade on your own serverRun a live SMTP session and watch the capability list, the STARTTLS command and the handshake result.
Run a check

Frequently Asked Questions

1. Is STARTTLS less secure than regular TLS?

The encryption is identical — same TLS versions, same ciphers, same certificates. What differs is how you get there. Implicit TLS is encrypted from the first byte, so there is nothing to downgrade. STARTTLS begins in plain text and upgrades on request, which leaves a window where an active attacker can remove the offer. Once the handshake completes, the two are equivalent.

2. Should I use port 587 with STARTTLS or 465 with implicit TLS?

For client submission either is fine, and the encryption ends up the same. Port 465 is marginally simpler because TLS is never optional — there is no plain-text window at all. Port 587 is more widely documented and more likely to be what your provider expects. The mistake to avoid is mismatching them: implicit TLS on 587 or STARTTLS on 465 hangs until it times out.

3. What is a STARTTLS stripping attack?

An attacker sitting between two mail servers deletes the 250-STARTTLS line from the plain-text capability list. The sender never learns the upgrade was available, falls back to cleartext, and delivers the message unencrypted. Neither side sees an error. MTA-STS and DANE exist to close exactly this gap by telling senders that TLS is mandatory for your domain.

4. Does STARTTLS mean my email is end-to-end encrypted?

No. It protects one hop between two servers. The message is decrypted on arrival, sits in plain text on that server, and is re-encrypted for the next hop only if that hop also offers TLS. Anyone with access to a server on the path reads the message. End-to-end encryption is PGP or S/MIME, which operates on the message body rather than the connection.

5. Why does my server show STARTTLS in EHLO but the handshake still fails?

Advertising the capability only means the server will accept the command. The handshake can still fail on an expired or wrong-hostname certificate, an untrusted chain, a TLS version the client refuses, or no shared cipher suite. Run openssl s_client -connect host:587 -starttls smtp and read the verify return code — it names the certificate problem directly.

6. How do I check whether my mail server offers STARTTLS?

Run the host through the SMTP Test — it shows the EHLO capability list, whether STARTTLS is advertised, and whether the upgrade actually succeeds. By hand, connect with openssl s_client -connect host:25 -starttls smtp -crlf and look for 250-STARTTLS in the response.

Related Articles