SMTP ports 25, 465, 587 and 2525: which one to use, and why the answer changed

Four ports, two TLS models, one deprecation that was later reversed. What each SMTP port is for, what a submission client should use today, and how to tell a connection problem from a TLS-mode mismatch.

The Mailclutch team5 min read

Every SMTP configuration screen asks for a port, and every one offers the same four choices. Two of them have official meanings, one was deprecated and then un-deprecated, and one is not registered for mail at all. Here is what each one is for and which one your application should be using.

The one-line answer

Use 587 with STARTTLS. If your library only does implicit TLS, use 465. If your host blocks both, use 2525. Never use 25 for submission.

The rest of this article is why.

Submission versus relay

SMTP does two different jobs with the same protocol, and the ports separate them.

Relay is server-to-server: your provider's MTA delivering to Gmail's MX. It happens on port 25, unauthenticated, between machines that decide whether to trust each other by IP reputation, SPF, DKIM and DMARC.

Submission is client-to-server: your application, or your mail client, handing a message to a server that will relay it. It happens on 587 or 465, authenticated — the server needs to know who you are, because it is about to send mail on your behalf.

RFC 6409 made this split explicit in 2011, and it is the reason submission has its own port: a server can require authentication and TLS on 587 while still accepting unauthenticated relay traffic from the world on 25.

Port 25: relay only

Port 25 is where mail servers talk to each other. It is also where spam comes from, which is why almost every residential ISP and most cloud providers block outbound 25 by default. AWS, Google Cloud, Azure, DigitalOcean, Hetzner — all of them either block it outright or require a request to unblock.

For submission this makes 25 useless: your application in a cloud VM cannot reach it. Even where it is reachable, submission servers commonly refuse AUTH on 25 or treat traffic there as inbound relay.

A sandbox that listens on 25 does it for one reason: a misconfigured relay that sends there — an application talking to localhost:25 in a container where nothing is listening, a Postfix pointed at the wrong relayhost — still ends up somewhere visible instead of a connection refused. It is a catch, not a recommendation.

Port 587: STARTTLS submission

587 is the submission port. The connection opens in clear text, the server advertises STARTTLS in its EHLO response, the client asks to upgrade, and from then on the session is TLS. Authentication happens after the upgrade.

C: EHLO app.example.com
S: 250-STARTTLS
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
   [TLS handshake]
C: EHLO app.example.com
C: AUTH PLAIN ...

This is what every major library defaults to, what every framework guide on this site configures, and what RFC 8314 recommends alongside 465. Its one weakness is the clear-text opening: an attacker on the path can strip the STARTTLS advertisement and a naive client will proceed unencrypted. Modern libraries refuse to authenticate if TLS was expected and not negotiated, so in practice this is a configuration matter — set the "require TLS" flag and the downgrade fails loudly.

Port 465: implicit TLS

465 was assigned to SMTPS in 1997, revoked in 1998 in favour of STARTTLS on 587, and then — after two decades of everyone using it anyway — formally re-established by RFC 8314 in 2018 as the port for implicit TLS: the connection is TLS from the first byte, exactly like HTTPS.

There is no STARTTLS on 465, because there is no clear-text phase to upgrade from. The client opens a TLS connection, and inside it the very first thing it sees is the 220 banner.

Security-wise, 465 is marginally cleaner than 587 — there is nothing to strip. Compatibility-wise, it is the port for clients that cannot do STARTTLS, which today mostly means some .NET SmtpClient configurations, certain managed platforms and older mail clients.

Most connection problems between 465 and 587 are a TLS-mode mismatch, not a network problem:

Port 465: implicit TLS
Client configured for Connects to What happens
STARTTLS 465 Client waits for a 220 banner in clear text; server waits for a TLS ClientHello. Both wait. Timeout.
Implicit TLS 587 Client sends a TLS ClientHello; server reads it as a garbage SMTP command. 500 5.5.2 Error: bad syntax, or the client reports an SSL handshake failure.

If a connection hangs for exactly the timeout, or fails with "wrong version number" or "unexpected EOF", check the TLS mode before checking the firewall.

Port 2525: the unofficial fallback

2525 is not assigned to anything by IANA. It became a convention because some networks block 587 as well as 25 — corporate proxies, some PaaS platforms, some residential ISPs — and 2525 is high enough to slip through. It behaves like 587: clear text with STARTTLS.

Most transactional providers and most sandboxes listen on it for this reason. Use it when 587 is unreachable and you have confirmed that it is the network, not the TLS mode.

What the server sees

For a server operator these four ports are one server with one difference: on 465, TLS is wrapped around the listener; on the other three, TLS is negotiated inside the session. Our own server does literally this — one configuration, four listeners, and one if p == ":465" deciding whether to call ListenAndServeTLS or ListenAndServe.

That symmetry is worth knowing when you debug. If a pair of credentials works on 587 and fails on 465, the credentials are not the problem and neither is the server's idea of them; the TLS mode is.

Choosing, in practice

  1. Default to 587, with your library's "require TLS" / STARTTLS option on.
  2. If the library only offers an "SSL" or "implicit TLS" toggle, use 465 with that toggle on.
  3. If you get a connection timeout on both, try 2525 with STARTTLS. If that works, the network is filtering the standard ports.
  4. Never submit on 25.

For the exact settings in Laravel, Django, Rails, Node.js, Spring and the rest, the framework guides show each one against a live sandbox — including which TLS toggle each library calls what, which is the part that actually varies.

Checking a port from the command line

# Is anything listening? (587 / 2525 / 25 — expect a 220 banner)
nc -vz smtp.mailclutch.com 587

# STARTTLS handshake on 587
openssl s_client -connect smtp.mailclutch.com:587 -starttls smtp -brief

# Implicit TLS on 465 — note: no -starttls
openssl s_client -connect smtp.mailclutch.com:465 -brief

If the first succeeds and the second fails, the port is open and TLS is the problem. If the first fails, it is the network. If both succeed and your application still cannot connect, the application's TLS mode is set for the other port.

Related articles

Keep reading

All articles

Read about it here, check it on your staging.

See it on your own mail

Point your staging SMTP at Mailclutch and every message comes back with its headers, its spam score and its authentication results — before a customer sees it.

Free plan · no credit card · running in under a minute