toolhq.io

All posts
6 min readby Jameel Haider

SMTP ports explained: 25, 465, 587, and which one you should use

Mail clients and libraries offer three SMTP ports and two encryption settings, and the combinations are not interchangeable. Choosing wrongly produces connections that hang without an error, or that succeed while sending credentials in the clear. The rule is short: use 587 with STARTTLS, or 465 with implicit TLS, and never use 25 to send mail from an application. Here is why each port exists and what actually differs.

PortPurposeEncryptionAuthenticationUse it for
25Server to server relayOpportunistic STARTTLSNoneReceiving mail only
587Client submissionSTARTTLS, requiredRequiredSending from your app
465Client submissionImplicit TLS from connectRequiredSending from your app
2525Unofficial alternativeSTARTTLSRequiredWhen 587 is blocked

Port 25: for servers talking to servers

Port 25 is how mail actually moves between organizations. When someone sends you a message, their mail server looks up your domain's MX records and connects to the named host on port 25. That connection is anonymous by design, since there is no account relationship between two strangers' mail servers, and encryption is opportunistic: the sending server issues STARTTLS if the receiver advertises it, and falls back to plaintext if not.

That anonymity is exactly why port 25 is unusable for applications. Because anyone can connect to it, it was the vehicle for essentially all spam sent from compromised machines, and the response was near universal blocking of outbound port 25 on residential, cloud, and office networks. AWS, Google Cloud, Azure, and most consumer ISPs block it by default and grant exceptions rarely. Your app connecting to port 25 typically does not fail fast; it hangs until the connection times out, which is why this shows up as an intermittent mystery rather than a clear error.

Your mail server still needs to accept connections on port 25, since that is the only way inbound mail arrives. Inbound and outbound are separate concerns here. You can confirm which hosts should be listening for your domain with the MX Lookup tool.

Port 587: submission with STARTTLS

Port 587 is the submission port, defined for exactly one job: an authenticated client handing a message to its own provider for delivery. It requires authentication, which means it is not an open relay, which means it is not blocked the way 25 is.

Encryption on 587 is explicit. The connection opens in plaintext, the client issues STARTTLS, and the session is upgraded before authentication happens:

220 smtp.example.com ESMTP ready
EHLO client.example.com
250-STARTTLS
STARTTLS
220 2.0.0 Ready to start TLS
        <- TLS handshake happens here ->
EHLO client.example.com
AUTH LOGIN ...

The risk in explicit TLS is that the upgrade is a request rather than a guarantee. A client configured to continue if STARTTLS fails will happily send credentials in plaintext, and an on path attacker can force that by stripping the STARTTLS advertisement from the server's greeting. Every serious library exposes a setting for this, variously named requireTLS, starttls: required, or similar. Set it. A connection that fails is better than one that silently downgrades. The wider protection against downgrade attacks at the domain level is MTA-STS.

Port 465: submission with implicit TLS

Port 465 has a confusing history. It was assigned for SMTPS, revoked in 1998 in favour of STARTTLS, used widely anyway for two decades, and then formally re registered in 2018 for message submission over implicit TLS. It is a current, standard, recommended port, not a legacy one, and advice calling it deprecated predates the 2018 revision.

Implicit TLS means the TLS handshake happens immediately on connect, before any SMTP command. There is no plaintext phase and therefore nothing to strip, which makes 465 structurally safer than 587 against downgrade attacks. This is the same pattern as HTTPS on 443 versus an HTTP upgrade, and the reasoning in HTTP vs HTTPS applies directly.

Choosing between them: 465 is the marginally safer default because the failure mode does not exist. 587 is more universally supported, particularly by older libraries and appliances. Either is correct when configured properly; what matters more than the choice is that TLS is enforced rather than attempted. If your provider supports both, take 465.

The one thing that gets misconfigured constantly is the mismatch: pointing a client at 465 with STARTTLS enabled, or at 587 with implicit TLS. Both hang rather than erroring clearly, because each side is waiting for the other to speak first. In most libraries the settings look like:

Port 465:  secure: true    (or ssl: true, tls: true)
Port 587:  secure: false   (or starttls: required)

The naming is unhelpful, since secure: false on 587 still produces an encrypted session; it means "do not start in TLS", not "do not encrypt".

Testing a connection

# Implicit TLS on 465
openssl s_client -connect smtp.example.com:465 -crlf

# Explicit TLS on 587
openssl s_client -starttls smtp -connect smtp.example.com:587 -crlf

Both print the certificate chain and drop you into an SMTP session where EHLO example.com shows the advertised capabilities, including whether AUTH is offered. If the certificate is the problem rather than the port, decode it with the SSL Decoder or check the host with the SSL Checker; mail servers frequently present certificates that do not match the hostname clients were told to use, and strict clients refuse those.

Getting mail delivered, not just sent

Choosing the right port gets the message out of your application. Whether it reaches an inbox is a separate matter governed by domain authentication: SPF, DKIM, and DMARC must all be aligned for your sending source. Confirm your domain's records with the email health checker and generate correct ones with the SPF generator and DMARC generator. The full pre launch list is in the email deliverability checklist.