SMTP settings tell your application how to hand a message to a mail relay. You need four things: a host name, a port, an encryption mode and a username and password. Choose port 587 with STARTTLS unless you have a reason not to, keep the connection encrypted, and send from a domain you have authenticated. This guide explains each setting and gives working examples for PHP, Python and Node.js.
Use your own values. The host name, username and password in this guide are placeholders. Copy the real values from the SMTP section of your MigoSMTP dashboard, and check there which ports and limits your plan supports.
The short version
- Host. The SMTP server name from your dashboard, for example
smtp.example.com. - Port and security. Port 587 with STARTTLS, or port 465 with SSL/TLS. Not both settings at once.
- Authentication. Your SMTP username and password, sent only after the connection is encrypted.
- From address. An address on a domain you have authenticated with SPF, DKIM and DMARC.
- Test. Check the connection with
openssl, then send one test message from your application.
The four settings
| Setting | What it is | Example |
|---|---|---|
| Host | The name of the relay server your application connects to | smtp.example.com |
| Port | The network port on that server. It decides how encryption starts | 587 or 465 |
| Encryption | STARTTLS (upgrade after connecting) or SSL/TLS (encrypted from the start) | STARTTLS on 587, SSL/TLS on 465 |
| Username and password | The credentials of your SMTP user, used for AUTH | Set as environment variables |
Which port should you use?
| Port | Used for | Encryption | When to choose it |
|---|---|---|---|
| 587 | Message submission (RFC 6409) | STARTTLS, required | The default choice for applications, websites and most libraries |
| 465 | Submission over implicit TLS (RFC 8314) | TLS from the first byte | When your client or device supports it and you prefer encryption from the start |
| 25 | Server-to-server delivery | Opportunistic STARTTLS | Not for applications. Outbound port 25 is often blocked |
| 2525 | Unofficial alternative submission port | STARTTLS | Only when 587 is blocked by your network, and only if your provider offers it |
Never send credentials in plain text. If a client offers a setting called None or Unencrypted, do not use it with a login. Always use STARTTLS or SSL/TLS, and make the client fail if encryption cannot be established.
STARTTLS and SSL/TLS
On port 587 the client connects in plain text, asks the server what it supports, then sends the STARTTLS command to switch to an encrypted session. Only after that does it log in. On port 465 the TLS handshake happens immediately, before any SMTP command. Both end up equally protected as long as the client does require the upgrade: a client that continues in plain text when STARTTLS fails is open to a downgrade attack.
| STARTTLS (587) | Implicit TLS (465) | |
|---|---|---|
| First bytes on the wire | Plain SMTP greeting | TLS handshake |
| Setting name in many apps | TLS, STARTTLS or Explicit TLS | SSL, SSL/TLS or Implicit TLS |
| Downgrade risk if misconfigured | Yes, if the client does not require TLS | No, there is no plain phase |
| Library support | Universal | Universal in modern libraries |
Authentication
After the encrypted session starts, the client logs in with the SMTP AUTH command, usually with the PLAIN or LOGIN mechanism. These send the username and password in a reversible encoding, which is safe only because the connection is already encrypted. That is why TLS must come first.
- Use SMTP credentials, not your account login. They can be rotated without locking you out of the dashboard.
- Keep them secret. Put them in environment variables or a secrets manager, never in source control or client-side code.
- One credential per application. If one is exposed you can revoke it without breaking everything else.
- Rotate on a schedule and immediately after any suspected leak.
Test the connection first
Before debugging application code, check that the server is reachable and TLS works from the machine that will send. For port 587:
openssl s_client -starttls smtp -connect smtp.example.com:587 -crlf
For port 465:
openssl s_client -connect smtp.example.com:465 -crlf
A good result shows the certificate chain, a TLS protocol version of 1.2 or 1.3 and a 220 greeting from the server. If the command hangs, the port is blocked or the host name is wrong.
Send a message from code
PHP with PHPMailer
use PHPMailer\PHPMailer\PHPMailer;
$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host = getenv('SMTP_HOST');
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true;
$mail->Username = getenv('SMTP_USER');
$mail->Password = getenv('SMTP_PASS');
$mail->setFrom('hello@mail.example.com', 'Example');
$mail->addAddress('user@example.net');
$mail->Subject = 'Test message';
$mail->Body = 'It works.';
$mail->send();
Python with smtplib
import os, smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["From"] = "hello@mail.example.com"
msg["To"] = "user@example.net"
msg["Subject"] = "Test message"
msg.set_content("It works.")
with smtplib.SMTP(os.environ["SMTP_HOST"], 587, timeout=30) as s:
s.starttls()
s.login(os.environ["SMTP_USER"], os.environ["SMTP_PASS"])
s.send_message(msg)
Node.js with Nodemailer
const nodemailer = require("nodemailer");
const transport = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: 587,
secure: false, // false for STARTTLS on 587, true for port 465
requireTLS: true, // fail instead of sending in plain text
auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
});
await transport.sendMail({
from: "hello@mail.example.com",
to: "user@example.net",
subject: "Test message",
text: "It works.",
});
Note on the secure option. In Nodemailer, secure: true means implicit TLS and is meant for port 465. For port 587 keep secure: false and set requireTLS: true so the upgrade is mandatory.
Good sending habits
- Reuse connections. Opening a new TLS session for every message is slow. Keep a connection open and send many messages through it, within your provider limits.
- Set timeouts. Use a connect and a read timeout of about 30 seconds so a stuck connection does not block your application.
- Retry 4xx, stop on 5xx. A 4xx reply is temporary: retry with a growing delay. A 5xx reply is permanent: log it and do not retry. See the bounce code guide.
- Log the full reply. Store the complete server response, not only the code. The text usually names the problem.
- Send from an authenticated domain. Set up SPF, DKIM and DMARC first, as described in authenticate a sending domain.
- Queue in your application. Put messages on a queue and send from a worker, so a slow relay never slows a web request.
Common errors and fixes
| Error | Likely cause | Fix |
|---|---|---|
| Connection timed out | Port blocked, wrong host or firewall | Test with openssl from the same server, try 587 or 465, check outbound firewall rules |
535 5.7.8 authentication failed | Wrong username or password | Re-copy the SMTP credentials, check for spaces and special characters |
530 5.7.0 must issue STARTTLS first | Client is not using TLS | Enable STARTTLS on 587, or SSL/TLS on 465 |
| SSL: WRONG_VERSION_NUMBER | Implicit TLS used on a STARTTLS port, or the reverse | Match the setting to the port: 587 with STARTTLS, 465 with SSL/TLS |
| Certificate verify failed | Wrong host name or an outdated CA bundle | Connect using the host name on the certificate and update the CA certificates |
550 5.7.1 relay denied | Sender or recipient not allowed for this account | Check the From domain is verified in your dashboard |
552 message too large | Attachments exceed the size limit | Reduce attachment size or link to files instead |
421 or 450 too many connections | Rate or connection limit reached | Reuse connections, slow down and retry later |
Stuck on a connection error? Send us the full error text and the port you tried, and we will help you find the cause.
Further reading and sources
- RFC 6409: Message Submission for Mail
- RFC 8314: Cleartext Considered Obsolete: Use of TLS for Email Submission and Access
- RFC 3207: SMTP Service Extension for Secure SMTP over TLS
- RFC 4954: SMTP Service Extension for Authentication
- PHPMailer documentation
- Nodemailer SMTP transport documentation
- Related guides: SMTP bounce codes explained and Authenticate a sending domain.
Frequently asked questions
Which SMTP port should I use?
Use port 587 with STARTTLS for most applications. It is the standard port for message submission. Use port 465 with implicit TLS if your library or device prefers an encrypted connection from the first byte. Port 25 is for server-to-server delivery and is often blocked for outbound traffic, and port 2525 is an unofficial alternative used when 587 is blocked.
What is the difference between port 587 and port 465?
Both are used to submit mail from your application to a relay. Port 587 starts as a normal connection and upgrades to TLS with the STARTTLS command. Port 465 is encrypted from the first byte, which is called implicit TLS or SMTPS. Either is secure when TLS is enforced, and RFC 8314 recommends implicit TLS where it is available.
What is the difference between STARTTLS and SSL/TLS?
STARTTLS upgrades an existing plain connection to an encrypted one after a command. SSL/TLS, also called implicit TLS, encrypts the connection immediately. Many mail settings screens call the second option SSL, but the protocol in use today is TLS. Choose the option that matches the port.
Why is port 25 blocked?
Many internet providers and cloud platforms block outbound port 25 by default to stop infected machines from sending spam directly. Applications should submit mail on port 587 or 465 to a relay instead of connecting to receiving servers on port 25.
What is my SMTP username and password?
They are the credentials created for your sending account or your SMTP user in the dashboard. They are usually not your login for the web interface. Store them in an environment variable or a secrets manager and rotate them if they might have been exposed.
What does error 535 authentication failed mean?
The relay rejected your username or password. Check for typos and extra spaces, confirm you are using the SMTP credentials and not the account login, and make sure special characters in the password are not being changed by your configuration file or shell.
What does 530 5.7.0 Must issue a STARTTLS command first mean?
The server requires an encrypted connection before it accepts a login. Enable STARTTLS on port 587 or switch to implicit TLS on port 465 in your client settings.
Why does my connection time out?
A timeout usually means the port is blocked by a firewall, a hosting provider or your network, or that the host name or port is wrong. Test with openssl s_client from the same server and try an alternative port.
Can I send without authentication?
Not on a public relay. Authentication ties each message to your account, protects the relay from abuse and lets the provider apply your limits and reputation. Some private relays allow sending from an approved IP address, but this should be a deliberate setup and not a way around credentials.
How many messages can I send over one connection?
Most relays allow many messages per connection, and reusing a connection is much faster than opening a new one for every message. The exact limits for connections, messages per connection and recipients per message depend on your provider and plan, so check your account limits.