"535 5.7.8 Username and Password not accepted" means the mail server read your credentials at the AUTH step and rejected them. The 5 makes it permanent — retrying the same credential will fail identically forever — and the 5.7.x enhanced code places it in the security and policy category. The important thing to understand is that this is rarely a mistyped password. In the large majority of cases the password is correct but is the wrong kind of credential for that provider.
What the Error Looks Like
The exact wording varies by provider, but the 535 and the 5.7.x code are consistent. Some providers use their own extended detail digits:
# Gmail / Google Workspace
535-5.7.8 Username and Password not accepted. For more information, go to
535 5.7.8 https://support.google.com/mail/?p=BadCredentials
# Microsoft 365 — note the extended 5.7.139
535 5.7.139 Authentication unsuccessful, SmtpClientAuthentication is disabled
for the Tenant. Visit https://aka.ms/smtp_auth_disabled for more information.
# Generic Postfix / Dovecot
535 5.7.8 Error: authentication failed: (reason withheld)
# Some servers use 5.7.0 instead of 5.7.8
535 5.7.0 Invalid login or passwordIn application logs the same failure usually surfaces wrapped by the library — PHPMailer reports SMTP Error: Could not authenticate, Nodemailer throws Invalid login: 535-5.7.8, and Python's smtplib raises SMTPAuthenticationError. All three are the same server reply.
Test the credential against your server
Why It Happens — By Provider
Each major provider rejects a different thing. Find yours before changing anything, because the generic advice ("check your password") is wrong for most of them.
Gmail and Google Workspace
Google does not accept your account password over SMTP. With 2-Step Verification enabled you must generate a 16-character App Password and use that instead. Accounts without 2-Step Verification cannot create one at all — and the old "less secure app access" setting that previously allowed the account password has been removed, so enabling 2-Step Verification is now a prerequisite rather than an obstacle.
The username is your full address, including the domain. A related code, 534 5.7.9 Application-specific password required, is Google telling you the same thing more explicitly.
Microsoft 365 and Outlook
Microsoft disables SMTP AUTH at the tenant level by default, and the reply carries the distinctive 5.7.139 detail code. No password will work until authenticated SMTP is enabled for the specific mailbox — this is a policy setting, not a credential problem:
# Enable SMTP AUTH for one mailbox (Exchange Online PowerShell)
Set-CASMailbox -Identity user@example.com -SmtpClientAuthenticationDisabled $false
# Check the current tenant-wide setting
Get-TransportConfig | Format-List SmtpClientAuthenticationDisabledSecurity Defaults, which are on for most modern tenants, also block basic authentication outright. Where they are enforced, the supported path is OAuth 2.0 (XOAUTH2) rather than a username and password, or a dedicated application that supports modern authentication.
SendGrid
The username is the literal string apikey — not your account email, not your login name. The password is the API key itself, and that key needs Mail Send permission. Using your SendGrid account credentials produces a 535 every time.
Amazon SES
SES SMTP credentials are not your AWS access key and secret key. They are generated separately in the SES console, and the SMTP password is derived from the secret through a signing algorithm — pasting the raw AWS secret will always fail. The credentials are also region-specific: credentials created in us-east-1 will be rejected by email-smtp.eu-west-1.amazonaws.com, which is a common and confusing cause of 535 after a region migration.
Zoho Mail
Accounts with two-factor authentication require an application-specific password generated from the account security settings. The regular password is refused.
Mailgun, Brevo, Postmark and Mailchimp Transactional
All four separate the SMTP credential from the account login. Mailgun issues per-domain SMTP credentials with a postmaster@ username; Brevo uses an SMTP key from the SMTP & API page; Postmark uses the Server API token as both username and password; Mailchimp Transactional uses a Mandrill API key as the password. In every case, the dashboard login will produce a 535.
Causes That Apply to Any Server
1. The username is not in the expected form
Some servers want the full email address, others want only the local part, and a few want a separate system username. user and user@example.com are not interchangeable — try the other form before assuming the password is wrong.
2. Whitespace or an invisible character in the credential
Copying an API key or app password frequently picks up a trailing newline or space, and Google displays app passwords in four groups of four which people sometimes paste with the spaces intact. Both produce a 535 with a credential that looks correct on screen.
3. AUTH attempted before the connection is encrypted
Most servers advertise AUTH only after STARTTLS has upgraded the connection, and refuse credentials sent in clear text. Depending on the server this surfaces as 530 5.7.0 Must issue a STARTTLS command first, 503, or a plain 535. Check the EHLO response before and after the upgrade — if AUTH appears only in the second one, the client must upgrade first.
4. An authentication mechanism the server does not offer
A client forced to CRAM-MD5 against a server offering only LOGIN and PLAIN will fail even with a valid password. Let the client negotiate automatically from the EHLO capability list rather than pinning a mechanism.
5. The credential was rotated, expired, or the account is locked
API keys get revoked, app passwords get deleted when 2-Step Verification is reset, and accounts get locked after repeated failed attempts. A credential that worked yesterday and fails today with no configuration change points here first.
421 or 454. Fix the credential before retrying in a loop, and disable any automated retry while you test.How to Diagnose It
Reproduce the failure by hand, outside your application, so you can see the server's exact reply rather than the library's interpretation of it. First check which mechanisms are offered:
# Connect and upgrade, then read the capability list
openssl s_client -connect smtp.example.com:587 -starttls smtp -crlf
# Then type:
EHLO test.example.net
# Look for the AUTH line in the reply:
# 250-AUTH LOGIN PLAIN XOAUTH2
# If AUTH is absent, the server will not accept credentials on this connection.Then perform the AUTH exchange manually. AUTH LOGIN takes the username and password as separate base64 strings, which also lets you verify that what you are sending contains no stray whitespace:
# Encode each part separately — note -n, which prevents a trailing newline
printf '%s' 'user@example.com' | base64
printf '%s' 'your-app-password' | base64
# In the open session:
AUTH LOGIN
334 VXNlcm5hbWU6 ← "Username:" — send the base64 username now
334 UGFzc3dvcmQ6 ← "Password:" — send the base64 password now
# Success looks like:
235 2.7.0 Authentication successful
# Failure is the error you came here for:
535 5.7.8 Username and Password not acceptedVXNlcm5hbWU6 decodes to Username: and UGFzc3dvcmQ6 to Password:. If you see a different 334 prompt, the server is asking for something else and your client is answering the wrong question.How to Fix It
Fix A — Use the credential type the provider expects
This resolves the majority of cases. Match your provider to the credential it actually wants:
| Provider | Username | Password |
|---|---|---|
| Gmail / Workspace | Full email address | 16-character App Password (2FA required) |
| Microsoft 365 | Full mailbox address | Account password — only after SMTP AUTH is enabled |
| SendGrid | The literal apikey | API key with Mail Send permission |
| Amazon SES | SES SMTP username | SES SMTP password, from the correct region |
| Zoho Mail | Full Zoho address | Application-specific password |
| Mailgun | postmaster@your-domain | Domain SMTP password |
| Postmark | Server API token | The same Server API token |
| Brevo | Brevo login address | SMTP key from the SMTP & API page |
Fix B — Enable SMTP authentication on the mailbox
On Microsoft 365 specifically, the credential cannot succeed while the tenant or mailbox has SMTP AUTH disabled. Enable it per mailbox with Set-CASMailbox as shown above, confirm Security Defaults are not blocking basic authentication, and re-test. If organisational policy forbids enabling it, move the application to OAuth 2.0.
Fix C — Re-enter the credential cleanly
Retype rather than paste, or strip whitespace explicitly. Storing the credential in an environment variable makes stray characters visible and keeps it out of your source:
# Reveal trailing whitespace or newlines in a stored credential
printf '[%s]' "$SMTP_PASS" # brackets make stray spaces obvious
# Strip a trailing newline when reading from a file
SMTP_PASS="$(tr -d '\r\n' < /run/secrets/smtp_password)"For Google app passwords, remove the display spaces — the credential is sixteen characters with no separators.
Fix D — Let the client negotiate STARTTLS and the mechanism
Set the client to port 587 with STARTTLS (or 465 with implicit TLS) and leave the authentication method on automatic. This avoids both the "AUTH before encryption" failure and the mechanism mismatch:
// Nodemailer — correct pairing, mechanism negotiated from EHLO
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false, // 587 upgrades with STARTTLS; use true only for 465
requireTLS: true, // refuse to send credentials on an unencrypted link
auth: {
user: process.env.SMTP_USER, // full email address
pass: process.env.SMTP_PASS, // app password, no spaces
},
});Fix E — Regenerate the credential
If everything above checks out, issue a new app password or API key and try that. Revoked and silently expired credentials are common enough that regenerating is faster than proving the old one is still valid — and it costs nothing when the credential is single-purpose.
Frequently Asked Questions
My password is definitely correct — why is it still rejected?
Because most providers no longer accept the account password over SMTP at all. Gmail and Zoho require an app-specific password, SendGrid wants an API key with the username apikey, and Amazon SES wants SMTP credentials generated in the SES console rather than your AWS keys. The password being correct for the web login is unrelated to whether it is valid for SMTP.
What is the difference between 535 5.7.8 and 535 5.7.139?
5.7.139 is Microsoft's extended code meaning authenticated SMTP is switched off for the tenant or mailbox. It is a policy block rather than a credential rejection, so no password change will help — SMTP AUTH has to be enabled first, or the application moved to OAuth.
Does a 535 mean my account was compromised?
Not on its own. It means the credential presented was refused, which is far more often a configuration or credential-type problem. That said, if a previously working credential suddenly fails and you did not change anything, check whether the provider force-reset the password or revoked the key — providers do that in response to suspicious activity.
Should I disable TLS to test whether encryption is the problem?
No. Most servers refuse credentials on an unencrypted connection, so disabling TLS makes authentication fail more, not less — and it sends the password in clear text over the network. If you suspect the upgrade is the issue, read the EHLO reply before and after STARTTLS to see when AUTH is advertised.
Can a firewall or blocked port cause a 535?
No. A 535 is a reply from the mail server, which means the connection succeeded, TLS negotiated, and the server processed your AUTH command. Network problems prevent the session from ever reaching that point and show up as timeouts or refused connections instead.