Why does your mail server keep rejecting your app with “authentication required”? SMTP authentication is the login step that lets your app send through that server.
Most SMTP libraries hide this step behind a single login() call. That’s handy until it fails, and the error only shows a 3-digit code.
In this guide, I’ll walk you through how SMTP authentication works, command by command.
What Is SMTP Authentication?
SMTP authentication (SMTP AUTH) makes your app log in before a mail server will send email for it. Your app sends a username and password, or a token. The server replies with a success or failure code.
RFC 4954 defines it, and it usually runs on port 587, the mail submission port.
Without it, the server can’t tell your app apart from a spammer’s script.
SMTP AUTH vs SPF, DKIM, and DMARC
SMTP AUTH and SPF, DKIM, and DMARC solve different problems. People mix them up because all four get called “email authentication.”
- SMTP AUTH proves to your email provider that your app is allowed to send email through your account. It happens before the email leaves.
- SPF, DKIM and DMARC prove to the receiving mail server, like Gmail or Outlook, that your domain authorized the email. They’re checked when the email arrives.
You need both. A logged-in app can still land in spam if your DNS records are missing.
Why Servers Require It
A server that sends mail for anyone, no login needed, is called an open relay. Spammers hunt for them, and blocklists flag them fast.
SMTP AUTH closes that door. The server only sends mail for apps that log in, which ties every message to an account.
It’s also how your provider tracks sending limits and stops abuse on shared IPs.
How SMTP Authentication Works, Step by Step
SMTP authentication is a short conversation between your app and the mail server. Your app says hello, asks to switch on encryption, logs in, and gets a yes or no.
Your app or plugin does all of this for you in a split second. You only need to follow along when you’re debugging a login problem.
I’ll show SendLayer’s real replies at each step, so you know what to expect.
Prerequisites
You’ll need 2 things to follow along:
- A terminal with
opensslinstalled. It ships with macOS and most Linux distributions. On Windows, it comes with Git for Windows, so you can use Git Bash. - An SMTP username and password from your email provider. On SendLayer, they’re under Settings » SMTP Credentials.
Step 1: Connect and Say EHLO
Your app connects to the server on port 587 and introduces itself with EHLO. The server replies with a list of everything it supports.
Here’s what SendLayer’s server sent back when I tested it while writing this post:
EHLO client.example.com
250-smtp.sendlayer.net greets client.example.com
250-SIZE 102400000
250-STARTTLS
250-AUTH LOGIN
250 ENHANCEDSTATUSCODES
Look for the STARTTLS line. It means the server can encrypt the connection if your app asks. At this point, nothing is encrypted yet.
Step 2: Upgrade the Connection With STARTTLS
To switch on encryption, your app sends one word: STARTTLS. The server agrees:
STARTTLS
220 2.0.0 Ready to start TLS
Right after that reply, your app and the server set up encryption. It’s the same kind your browser uses for HTTPS sites. From here on, anyone watching the network only sees scrambled data.
Then your app sends EHLO again, because the server’s list can change once the connection is encrypted. SendLayer’s did:
EHLO client.example.com
250-smtp.sendlayer.net greets client.example.com
250-SIZE 102400000
250-AUTH LOGIN PLAIN
250 ENHANCEDSTATUSCODES
Two things changed. STARTTLS is gone, since the connection is already encrypted. And the AUTH line now lists both LOGIN and PLAIN, the login methods the server accepts.
Note: You can’t do the encryption setup by typing. It’s an exchange of binary data, not words. So to try this yourself, let OpenSSL handle Steps 1 and 2 for you.
Run this command in your terminal:
openssl s_client -starttls smtp -connect smtp.sendlayer.net:587 -crlf -quiet
The -starttls smtp part tells OpenSSL to send STARTTLS and set up the encryption automatically. When it connects, type EHLO client.example.com and press Enter. You’ll see the encrypted reply shown above. Then carry on with Step 3.
Step 3: Send AUTH and Your Credentials
Your app picks a login method from the AUTH line and sends your username and password. Most apps pick AUTH PLAIN, which sends both in one line.
First, the username and password get packed into one string and converted to Base64. Base64 is a way of writing any data with plain letters and numbers, so it can travel safely inside an email command.
The packed string always has the same shape: an empty character (called a null byte), the username, another null byte, then the password. Your app builds this for you. To see it yourself, open a second terminal window and run this command with your own username and password in place of the placeholders:
printf '\0%s\0%s' 'your-smtp-username' 'your-smtp-password' | base64
# AHlvdXItc210cC11c2VybmFtZQB5b3VyLXNtdHAtcGFzc3dvcmQ=
Copy the string it prints. Then go back to your OpenSSL window, type AUTH PLAIN and a space, paste the string, and press Enter:
AUTH PLAIN AHlvdXItc210cC11c2VybmFtZQB5b3VyLXNtdHAtcGFzc3dvcmQ=
Anyone can turn that string back into your password with base64 --decode. Base64 is an encoding, not encryption.
Warning: That’s why STARTTLS has to come first. Without it, your password crosses the network in a form anyone can read.
Step 4: Read the Server’s Reply
The server answers with a status code that tells you whether the login worked. When I sent the placeholder credentials above, SendLayer’s server replied:
535 5.7.8 Authentication credentials invalid
With your real username and password, you’ll get a 235 reply instead. That means you’re logged in, and your app can start sending the email.
Here are the codes RFC 4954 defines, and what to do about each one:
| Code | Meaning | What to do |
|---|---|---|
235 2.7.0 | Authentication succeeded | Send your message |
334 | Server wants more data | Send the next credential |
535 5.7.8 | Credentials invalid | Check the username and password |
530 5.7.0 | Authentication required | Log in before MAIL FROM |
534 5.7.9 | Mechanism too weak | Pick a stronger mechanism |
538 5.7.11 | Encryption required | Run STARTTLS first |
454 4.7.0 | Temporary failure | Retry later |
The text after the code varies by server, but the numbers don’t. For codes beyond authentication, see what each SMTP reply code means.
When you’re done testing, type QUIT and press Enter. SendLayer’s server replies with 221 and closes the connection.
SMTP Authentication Mechanisms Compared
SMTP authentication mechanisms differ in how the credential travels. PLAIN and LOGIN send the password itself, while OAuth mechanisms send a short-lived token instead.
A mechanism is simply the login method your app uses. The AUTH line from Step 2 lists the ones a server accepts, and your app or library usually picks one for you. So you rarely need to choose by hand.
| Mechanism | What it sends | Needs TLS? | Status (IANA) |
|---|---|---|---|
| PLAIN | Username and password, one string | Yes | Common |
| LOGIN | Username, then password, separately | Yes | Obsolete, still widely used |
| CRAM-MD5 | A hash of the password | Recommended | Limited |
| XOAUTH2 | An OAuth 2.0 access token | Yes | Obsolete, still used by Gmail and Microsoft 365 |
| OAUTHBEARER | An OAuth 2.0 access token | Yes | Common |
AUTH PLAIN
PLAIN sends the username and password together in one Base64 string. RFC 4954 requires every AUTH server to support PLAIN over TLS.
It’s simple and safe, as long as the connection is encrypted.
AUTH LOGIN
LOGIN sends the same credentials in 2 rounds. The server prompts with a 334 reply. The client sends the username, then the password.
LOGIN never became an official standard. Nearly every server still accepts it because older mail clients depend on it.
CRAM-MD5
CRAM-MD5 never sends the password. The server sends a random challenge, and the client replies with a hash of it. A hash is a scrambled fingerprint made from the challenge and the password, and it can’t be turned back into the password.
That sounds safer, but the server has to store a secret for every user that works just like the password. If the server is hacked, attackers can log in with it. You’ll rarely see CRAM-MD5 offered today.
XOAUTH2 and OAUTHBEARER
OAuth mechanisms replace the password with an access token. A token is a temporary pass your app gets after you sign in and approve access, a bit like a hotel key card. Tokens expire, can be revoked, and don’t expose the account password.
XOAUTH2 is Google’s original version, and Microsoft 365 uses it too. OAUTHBEARER is the standardized version, defined in RFC 7628.
SendLayer’s server doesn’t advertise an OAuth mechanism. You log in with the SMTP username and password from your dashboard.
Microsoft Is Retiring Basic Auth for SMTP AUTH
Microsoft is turning off password-based SMTP AUTH (Basic auth) in Exchange Online in stages. Apps, printers, and scripts that log in with a password will need to switch.
Here’s the timeline Microsoft published in January 2026:
| When | What changes |
|---|---|
| Through December 2026 | Nothing. Basic auth keeps working. |
| End of December 2026 | Basic auth is off by default for existing tenants. Admins can turn it back on. |
| New tenants after December 2026 | Basic auth isn’t available by default. OAuth is the supported method. |
| Second half of 2027 | Microsoft announces the final removal date. |
Microsoft’s deprecation page points to that announcement for current dates. It also names the Microsoft Graph API as another way to send.
You have 3 options if your app logs in to Microsoft 365 with a password:
- Switch the app to OAuth 2.0 (XOAUTH2), if it supports it.
- Send through the Microsoft Graph API instead of SMTP.
- Send app mail through a dedicated SMTP service with its own credentials.
Option 3 is often a quick fix for a printer or plugin without OAuth. You change the host, username, and password, and nothing else. Our guide to Microsoft’s SMTP AUTH changes walks through each option in more detail.
SMTP Credentials vs API Keys
SMTP credentials and API keys both prove who you are, but they travel differently. SMTP sends a username and password over port 587. An email API sends a key in an HTTPS header.
Here’s how the 2 compare on SendLayer:
| SMTP | Email API | |
|---|---|---|
| Endpoint | smtp.sendlayer.net | https://console.sendlayer.com/api/v1/ |
| Port | 587 with STARTTLS | 443 (HTTPS) |
| Credential | SMTP username and password | API key |
| How it’s sent | AUTH PLAIN or AUTH LOGIN | Authorization: Bearer <API key> header |
| Best for | Plugins, apps, and devices with an SMTP setting | Your own code |
SendLayer creates your SMTP username and password when you authorize your domain. You’ll find them under Settings » SMTP Credentials, and they’re not your account login.
Your API key is on the API Keys tab, right next to the SMTP Credentials tab. To create a new key or revoke an old one, follow SendLayer’s guide to managing API keys.
Pro Tip: If your host blocks outbound port 587, use the email API instead. It runs over port 443, which hosts almost never block.
How to Authenticate in Code
Most languages handle SMTP authentication in 3 calls: connect, STARTTLS, then log in. Below, you’ll find examples for Python and Node.js, plus a no-code option for WordPress.
Both code examples read your credentials from environment variables, so they never land in your code or repository. An environment variable is a value your terminal hands to your program. Set yours like this in the same terminal window you’ll use to run the code:
export SENDLAYER_USER="your-smtp-username"
export SENDLAYER_PASS="your-smtp-password"
On Windows PowerShell, use $env:SENDLAYER_USER = "your-smtp-username" and $env:SENDLAYER_PASS = "your-smtp-password" instead.
Python (smtplib)
Python’s smtplib comes with Python, so there’s nothing to install. It picks a login method the server supports when you call login(). Save this code in a file called smtp_check.py:
import os
import smtplib
import ssl
host = "smtp.sendlayer.net"
user = os.environ["SENDLAYER_USER"]
password = os.environ["SENDLAYER_PASS"]
try:
with smtplib.SMTP(host, 587, timeout=15) as server:
server.starttls(context=ssl.create_default_context()) # Step 2
server.login(user, password) # Step 3
print("Authenticated")
except smtplib.SMTPAuthenticationError as err:
# 535 means bad credentials, 534 or 538 mean a mechanism or TLS problem
print("Login failed:", err.smtp_code, err.smtp_error.decode())
Run it with python3 smtp_check.py (or python smtp_check.py on Windows). If it works, your terminal prints Authenticated. For sending a full message, see our guide to sending email in Python.
Node.js (Nodemailer)
First, install Nodemailer in your project folder:
npm install nodemailer
Nodemailer’s verify() method logs in without sending anything, which makes it a handy credential check. Save this code in a file called smtp-check.mjs. The .mjs ending tells Node.js to accept the import and await lines:
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: "smtp.sendlayer.net",
port: 587,
secure: false, // start unencrypted, then upgrade
requireTLS: true, // refuse to log in without STARTTLS
auth: {
user: process.env.SENDLAYER_USER,
pass: process.env.SENDLAYER_PASS,
},
});
try {
await transporter.verify();
console.log("Authenticated");
} catch (err) {
console.error("Login failed:", err.responseCode, err.response);
}
requireTLS: true matters here. Without it, Nodemailer may log in unencrypted if STARTTLS isn’t offered.
Run it with node smtp-check.mjs. You’ll see Authenticated when the login works. To send a full message, see our Nodemailer guide.
WordPress (Easy WP SMTP)
WordPress doesn’t log in to a mail server on its own. By default, it hands emails to your web host’s mail function, with no SMTP authentication at all. That’s a common reason WordPress emails go missing.
An SMTP plugin like Easy WP SMTP fixes that, and you don’t need any code. Its Other SMTP mailer logs in to any SMTP server with a username and password. Here’s how to set it up with your SendLayer SMTP credentials.
First, install and activate the Easy WP SMTP plugin. Then go to Easy WP SMTP » Settings in your WordPress dashboard.
Under the list of mailers, click Other SMTP. Don’t confuse it with the SMTP tile at the top, which connects to the SMTP.com service.
Next, scroll down and fill in your server details:
- SMTP Host:
smtp.sendlayer.net - Type of Encryption: TLS. This is the STARTTLS upgrade from Step 2.
- SMTP Port:
587 - SMTP Authentication: On
- SMTP Username and SMTP Password: copy them from Settings » SMTP Credentials in SendLayer. Click Show Password to see the password, or use the copy icon next to it.
Then scroll to the bottom of the page and click Save Settings.
To check that the login works, go to Easy WP SMTP » Tools and open the Email Test tab. Enter your email address in the Send To field and click Send Test Email.
If the test email lands in your inbox, SMTP authentication is working. If the login fails, Easy WP SMTP shows “Could not authenticate your SMTP account.” Double-check the username and password, then send the test again.
If your host blocks port 587, pick the SendLayer mailer in Easy WP SMTP instead. It uses your SendLayer API key and sends over HTTPS, so the blocked port doesn’t matter.
For more detail on each Other SMTP field, see Easy WP SMTP’s guide to the Other SMTP mailer.
Fixing Common SMTP Authentication Errors
Most SMTP authentication errors come from 4 causes. Here’s how to fix each one.
530 5.7.0 Authentication Required
Your app sent MAIL FROM without logging in first. Check that your SMTP settings have authentication turned on and a username filled in.
In Easy WP SMTP, that’s the SMTP Authentication toggle. Other plugins may call it Authentication or Use SMTP Authentication.
535 5.7.8 Authentication Credentials Invalid
The server didn’t accept your username or password. On SendLayer, check that you used the SMTP password from Settings » SMTP Credentials, not your account login. In Easy WP SMTP, this error shows up as “Could not authenticate your SMTP account.”
Also check for a stray space at the end of a copied password.
Microsoft 365 uses its own variant, 535 5.7.3 Authentication unsuccessful, in its OAuth guide. It means the same thing.
534 5.7.9 or 538 5.7.11: Mechanism or Encryption Problem
A 534 means the server won’t accept the mechanism you chose. A 538 means it needs encryption for that mechanism.
Both often mean your app skipped STARTTLS. Set the encryption option to TLS or STARTTLS on port 587.
AUTH Isn’t Offered at All
If the EHLO reply has no AUTH line, the server may be waiting for STARTTLS. Run STARTTLS, then send EHLO again.
In an app or plugin, this usually means encryption is turned off. Set the encryption to TLS on port 587, save, and test again.
You can test this without writing code. Our SMTP test tool guide shows how to check any server’s login.
Frequently Asked Questions
Here are answers to the questions developers ask most about SMTP authentication.
Is SMTP authentication discontinued in Office 365?
Not yet. Microsoft plans to turn off Basic auth for SMTP AUTH at the end of December 2026. That applies by default to existing tenants. SMTP AUTH with OAuth 2.0 keeps working. Microsoft says it will announce the final removal date in the second half of 2027.
How do I fix an SMTP server authentication error?
Read the reply code first. A 535 means wrong credentials, and a 530 means you didn’t log in.
A 534 or 538 points to the mechanism or encryption. Fix the setting that matches the code, then test the login again.
How do I enable SMTP authentication?
In most apps and plugins, you turn it on by entering SMTP credentials. In WordPress, an SMTP plugin like Easy WP SMTP has an SMTP Authentication toggle.
In Microsoft 365, an admin turns it on for each mailbox under Users » Active users » Mail » Manage email apps » Authenticated SMTP. Microsoft documents this on its SMTP AUTH page.
Is SMTP authentication the same as SPF and DKIM?
No. SMTP authentication proves to your email provider that your app is allowed to send email through your account.
SPF and DKIM prove to the receiving mail server that your domain authorized the email. You need both for reliable delivery.
Is AUTH PLAIN secure?
AUTH PLAIN is secure over an encrypted connection. On its own, it only Base64-encodes your password, and anyone can decode that. Always run STARTTLS before you send AUTH PLAIN.
That’s it! Now you know how SMTP authentication works.
Next, learn what the other server replies mean in our guide to SMTP error codes. It covers the codes you’ll see after you log in, from 250 to 550.