Deliverability

SMTP SSL vs TLS: Which to Pick, STARTTLS or Implicit TLS

For SMTP, use TLS: SSL is deprecated. Pick implicit TLS on port 465 when offered, or STARTTLS on 587. Ports, RFCs and client settings explained.

TL;DR: In SMTP, "SSL" almost always means implicit TLS on port 465, and "TLS" usually means STARTTLS on port 587. The actual SSL protocols are deprecated, so both settings should negotiate TLS 1.2 or 1.3. When your provider offers both, RFC 8314 recommends implicit TLS on 465; use STARTTLS on 587 with "require TLS" turned on when 465 is unavailable.

The SMTP SSL vs TLS question is really about when encryption starts, not which cipher protocol you get. With implicit TLS (the "SSL" or "SSL/TLS" checkbox in most mail clients), the TLS handshake starts the moment the TCP connection opens on port 465. With STARTTLS (the "TLS" checkbox), the client connects in plaintext on port 587 or 25, the server advertises the STARTTLS capability, and the connection is upgraded before any login. SSL 2.0 and SSL 3.0 themselves were retired by RFC 6176 (2011) and RFC 7568 (2015), and TLS 1.0 and 1.1 by RFC 8996 (2021), so a modern server negotiates TLS 1.2 or TLS 1.3 either way.

Side by side: ports, standards and code settings

Criterion"SSL" setting (implicit TLS)"TLS" setting (STARTTLS)
Default submission port465587 (also 25 for relay)
When encryption startsBefore the first SMTP byteAfter EHLO and STARTTLS in plaintext
Defining standardRFC 8314 (Jan 2018)RFC 3207 (Feb 2002)
RFC 8314 preferencePreferred for submissionSupported during transition
Downgrade riskNone: no plaintext phaseStripping attack if the client does not require TLS
Protocol actually negotiatedTLS 1.2 or 1.3TLS 1.2 or 1.3
Nodemailer settingsecure: truesecure: false (+ requireTLS: true)
Python smtplibsmtplib.SMTP_SSLsmtplib.SMTP then .starttls()
Amazon SES ports465, 2465 ("TLS Wrapper")25, 587, 2587
Implicit TLS encrypts from the first byte, STARTTLS upgrades after a plaintext greeting
The highlighted rows travel in plaintext and are what a stripping attack targets.

Is SSL or TLS better for SMTP?

TLS is better, and it is the only option you should accept. SSL 2.0 is prohibited (RFC 6176) and SSL 3.0 is deprecated (RFC 7568) because of known breaks such as POODLE. TLS 1.0 and 1.1 followed in March 2021 (RFC 8996), and RFC 8314 says mail services still allowing SSL 2.x, SSL 3.0 or TLS 1.0 SHOULD move their users off them.

The confusion comes from labels. Many clients and providers still say "SSL" for port 465 because that port was first used with SSL in the 1990s. Google's SMTP relay help page, for example, tells you "For SSL, enter 465". Amazon SES calls the same mode "TLS Wrapper" and explicitly notes it is sometimes called SSL. Picking "SSL" in a modern client does not downgrade you to the SSL protocol; it picks implicit TLS. What you should check is the minimum protocol version: TLS 1.2, with TLS 1.3 (RFC 8446, August 2018) where both sides support it.

What is the difference between STARTTLS and implicit TLS?

STARTTLS is an SMTP command that upgrades an already-open plaintext connection to TLS; implicit TLS opens the connection inside TLS from the start. The resulting encryption is the same. The difference is the plaintext phase before the upgrade.

That phase is where the attacks live. In the USENIX Security 2021 paper "Why TLS is better without STARTTLS", Poddebniak, Ising, Böck and Schinzel tested mail clients and servers and found:

  • 15 of 28 clients were vulnerable to negotiation attacks, where a man in the middle strips the STARTTLS capability or injects an error so the client continues in plaintext.
  • A command injection bug first reported in 2011, where commands sent before the handshake are executed after it, was present in 8 of 23 server products tested and in about 2% of mail servers in an internet scan.
  • 16 of 28 clients accepted injected responses across the upgrade.

Their recommendation for users is to switch to implicit TLS and disable STARTTLS where possible. STARTTLS is still safe enough when the client requires the upgrade and refuses to continue without it; the danger is opportunistic STARTTLS, where a failed upgrade silently falls back to plaintext.

Video: USENIX Security '21 - Why TLS is better without STARTTLS: A Security Analysis of STARTTLS (USENIX)

Fabian Ising presents the USENIX Security 2021 research on STARTTLS. This part explains how STARTTLS adds a plaintext phase, how stripping and command injection attacks abuse it, and how many real clients and servers were affected.

  1. 0:56 Attacker model and STARTTLS vs implicit TLS
  2. 2:07 Microsoft and Apple submission support only STARTTLS
  3. 3:40 Stripping the STARTTLS capability
  4. 6:00 Command injection bug found in 8 of 23 servers

Which port should I use, 465 or 587?

Use 465 with implicit TLS when your provider supports it, and 587 with STARTTLS when it does not. RFC 8314 says clients and servers SHOULD implement both for the transition period and that Implicit TLS servers SHOULD be advertised in preference to STARTTLS ones. In practice:

  • Port 465: implicit TLS. Supported by Amazon SES (also 2465), Google (smtp.gmail.com and smtp-relay.gmail.com), and most transactional providers.
  • Port 587: STARTTLS submission. Supported almost everywhere, and the only option on some large providers: the USENIX authors note Microsoft and Apple offered only STARTTLS for submission at the time.
  • Port 25: server-to-server relay. Many cloud hosts block outbound 25, and STARTTLS on 25 is usually opportunistic. Do not use it for authenticated submission from an app.
  • Port 2525 / 2587 / 2465: alternates some providers (including SES for 2587 and 2465) offer when a network blocks the standard ports.

Our SMTP port 587 vs 465 vs 25 guide covers firewall and hosting restrictions per port, and the SMTP port reference lists provider defaults.

Choosing an SMTP encryption setting starts with whether port 465 is offered
Never accept a setting that lets the client fall back to plaintext.

How to configure each mode in code

Set the encryption mode to match the port; a mismatch is the most common cause of handshake timeouts and "wrong version number" errors.

Nodemailer (Node.js). secure: true means TLS from the first byte and defaults on for port 465. For 587, keep secure: false; Nodemailer upgrades with STARTTLS when offered, and requireTLS: true makes it fail instead of sending in plaintext.

// Implicit TLS on 465
const implicit = nodemailer.createTransport({
  host: "email-smtp.us-east-1.amazonaws.com",
  port: 465,
  secure: true,
  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
});

// STARTTLS on 587, refuse plaintext fallback
const starttls = nodemailer.createTransport({
  host: "email-smtp.us-east-1.amazonaws.com",
  port: 587,
  secure: false,
  requireTLS: true,
  tls: { minVersion: "TLSv1.2" },
  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
});

Python smtplib. SMTP_SSL wraps the socket in TLS immediately; SMTP plus starttls() upgrades. Pass a default context so the certificate and hostname are verified.

import smtplib, ssl

ctx = ssl.create_default_context()
ctx.minimum_version = ssl.TLSVersion.TLSv1_2

# Implicit TLS on 465
with smtplib.SMTP_SSL("smtp.example.com", 465, context=ctx) as s:
    s.login(user, password)
    s.send_message(msg)

# STARTTLS on 587
with smtplib.SMTP("smtp.example.com", 587) as s:
    s.starttls(context=ctx)  # raises if the server does not offer STARTTLS
    s.login(user, password)
    s.send_message(msg)

Check a server from the shell. OpenSSL shows the negotiated protocol for either mode:

# implicit TLS
openssl s_client -connect smtp.example.com:465 -brief
# STARTTLS
openssl s_client -connect smtp.example.com:587 -starttls smtp -brief

The Protocol version: line should read TLSv1.2 or TLSv1.3. Our Python SMTP guide has full send examples, and common SMTP errors covers the codes you see when the handshake succeeds but delivery fails.

Do I need an SSL certificate to send email?

No, not as a sender connecting to a provider. The server presents the certificate; your client only verifies it. You need your own certificate only if you run the receiving or submission server, where it must match the hostname clients connect to (for example smtp.yourdomain.com). What senders do need is domain authentication: SPF, DKIM and DMARC, which prove the mail is yours and are separate from transport encryption. See DKIM, SPF and DMARC explained.

Decision rules for a new app

Choose implicit TLS (465) if:

  • your provider offers it, which most transactional providers and Amazon SES do;
  • you want no plaintext phase and no possibility of a stripping downgrade;
  • you are configuring a new app and want the RFC 8314 recommended default.

Choose STARTTLS (587) if:

  • the provider supports only 587, as some large mailbox providers do;
  • a network or host blocks 465;
  • you can set the client to require TLS (requireTLS, "Require STARTTLS", starttls() that raises) so it never falls back.

Skipping SMTP entirely

For application email, SMTP encryption settings are one more thing to get wrong in each service and environment. An HTTPS email API removes the choice: every request is TLS by default, authentication is an API key rather than an SMTP password, and the response tells you whether the message was accepted. If that is your next step, SendHQ offers a Resend-compatible REST API for sending and receiving email from verified domains, with delivery and bounce events you can inspect per message.

FAQ

Is port 465 deprecated?

No. Port 465 was briefly reassigned in the late 1990s, which is why older guides call it deprecated, but RFC 8314 (2018) formally registered it for implicit TLS submission and prefers it over STARTTLS.

Is STARTTLS secure?

STARTTLS gives the same encryption as implicit TLS once the upgrade happens. It is secure when the client requires the upgrade; it is weak when the client silently continues in plaintext if STARTTLS is missing or fails.

What does "SSL/TLS" mean in my email client?

It means implicit TLS, usually on port 465. "STARTTLS" or plain "TLS" usually means the upgrade method on port 587. Both negotiate a TLS protocol version, not SSL.

Why do I get "wrong version number" or a timeout?

The encryption mode does not match the port: secure: true against 587 tries a TLS handshake on a plaintext greeting, and secure: false against 465 waits for a greeting that only arrives inside TLS. Match 465 to implicit TLS and 587 to STARTTLS.

Which TLS version should SMTP use?

TLS 1.2 at minimum and TLS 1.3 where available. TLS 1.0 and 1.1 were deprecated by RFC 8996 in March 2021.

Does SMTP TLS encrypt the email end to end?

No. Submission TLS protects the hop from your app to the provider. Server-to-server hops use their own, often opportunistic, STARTTLS on port 25. End-to-end encryption needs S/MIME or OpenPGP.

Sources: RFC 8314, RFC 3207, RFC 8996, RFC 7568, Amazon SES SMTP connection docs, Nodemailer SMTP transport, Python smtplib.