All articlesTroubleshooting

How to Fix SMTP Authentication Errors (535, 530, 534)

A practical, copy-paste friendly guide to debugging SMTP authentication failures across Gmail, Microsoft 365, SendGrid, and self-hosted servers.

The SMTPTester Team September 12, 2025 16 min read

Why SMTP authentication fails

SMTP authentication errors return a 5xx response code that tells you exactly what the server rejected. The most common ones you will see are 535 (invalid credentials), 530 (authentication required), and 534 (mechanism too weak). Decoding the response is the fastest way to fix the problem instead of guessing.

When SMTPTester runs your check, it shows the exact reply string from the server. Read that first — it almost always names the cause. A server that says "5.7.8 Username and Password not accepted" is telling you something very different from "5.7.0 Must issue a STARTTLS command first", even though both look like generic failures inside your application logs.

The single most useful habit you can build is this: never debug SMTP from your application's error message. Application frameworks wrap, translate, and truncate SMTP replies. Always reproduce the failure against the raw server, then fix the root cause.

The 60-second triage checklist

Before you change any code, run through this list. In our experience roughly nine out of ten authentication tickets are solved here:

  1. Can you reach the host at all? A hang with no reply is a firewall problem, not an auth problem.
  2. Are you on a submission port (587 or 465) rather than port 25?
  3. Is TLS actually negotiated before you send credentials?
  4. Is the username the full email address?
  5. Is the password an app password or API key rather than the account password?
  6. Has the mailbox been granted permission to use SMTP by an administrator?

Work top to bottom. Each step depends on the one above it, so fixing step 4 while step 2 is still wrong will simply produce a different error message.

535 5.7.8 — Authentication credentials invalid

This is the classic "wrong username or password" reply, but the underlying cause is usually subtler. Walk through this checklist:

  1. Use the full email address as the username. Most providers (Gmail, Microsoft 365, Zoho, FastMail) require the full address, not just the local part.
  2. Generate an app password. Google, Microsoft, Apple, and Yahoo all block regular passwords for SMTP when 2FA is enabled. Create a dedicated app password and use that 16-character token instead.
  3. Check for whitespace. Pasting from a password manager often introduces a trailing space. Re-type the value into SMTPTester to rule it out.
  4. Verify the account is allowed to send. Some Microsoft 365 tenants disable SMTP AUTH by default; an administrator needs to enable it per mailbox.
  5. Watch for character encoding. Passwords containing non-ASCII characters must be encoded correctly before Base64. Some older libraries mangle them silently.
  6. Confirm the account is not locked. Repeated failed attempts trigger temporary lockouts on most providers; the reply stays 535 even after you fix the password.

A useful trick: change the password to a simple alphanumeric test value for five minutes. If authentication suddenly succeeds, your problem was encoding or escaping — not credentials.

530 5.7.0 — Authentication required

A 530 reply means the server accepted your connection but refused to relay until you authenticate. Two common causes:

  • You connected to port 25 instead of the submission port (587 or 465).
  • You issued MAIL FROM before AUTH. SMTPTester always authenticates first, so if you see this in our diagnostics it usually means your client library is misconfigured.

There is a third, less obvious cause. Some servers advertise AUTH only *after* STARTTLS completes. If your client reads the EHLO response before upgrading the connection, it sees no AUTH capability, silently skips authentication, and then trips over 530 at MAIL FROM. The fix is to re-issue EHLO after the TLS upgrade — a step the SMTP specification requires and a surprising number of hand-rolled clients skip.

534 5.7.9 — Authentication mechanism too weak

The server requires a stronger mechanism than the one you offered. The most common scenario is presenting AUTH LOGIN over an unencrypted channel. Fix it by enabling STARTTLS on port 587 (or switch to implicit TLS on 465). If your client only supports plain auth, upgrade the library — modern providers will eventually drop legacy mechanisms entirely.

You will also meet 534 when a mailbox is protected by conditional access or modern authentication policies. In that case no password-based mechanism will ever succeed; the tenant expects XOAUTH2 with a token issued by the identity provider.

The other codes you will meet

CodeMeaningUsual fix
421Service not available, closing channelRate limit or throttling — slow down and retry
454 4.7.0Temporary authentication failureProvider-side issue; retry with backoff
501Syntax error in parametersMalformed Base64 or missing argument
538Encryption required for requested mechanismEnable STARTTLS before AUTH
550 5.7.1Relay access deniedAuthenticated, but not allowed to send as that address

The distinction between 4xx and 5xx matters a great deal in production. A 4xx is temporary: queue the message and retry with exponential backoff. A 5xx is permanent: retrying the identical request will fail identically and only damages your sender reputation.

Reading a real SMTP conversation

Understanding the wire protocol makes every error obvious. Here is a healthy session on port 587:

S: 220 smtp.example.com ESMTP ready
C: EHLO client.example.org
S: 250-smtp.example.com
S: 250-STARTTLS
S: 250-SIZE 35882577
S: 250 8BITMIME
C: STARTTLS
S: 220 2.0.0 Ready to start TLS
   <TLS handshake>
C: EHLO client.example.org
S: 250-AUTH LOGIN PLAIN XOAUTH2
S: 250 8BITMIME
C: AUTH LOGIN
S: 334 VXNlcm5hbWU6
C: <base64 username>
S: 334 UGFzc3dvcmQ6
C: <base64 password>
S: 235 2.7.0 Accepted

Three details are worth memorising. First, AUTH is only advertised after STARTTLS on a correctly configured server. Second, the 334 challenges are Base64-encoded prompts, not errors. Third, 235 is the only success code for authentication — anything else is a failure, even if your library reports "connected".

Gmail specifics

For smtp.gmail.com on port 587 with STARTTLS:

Username: you@gmail.com
Password: <16-char app password>

If you use Google Workspace, an administrator may also need to enable "Less secure app access" alternatives — typically by issuing OAuth-based credentials and switching to XOAUTH2. SMTP with app passwords still works for most Workspace tenants as of 2025.

Common Gmail-specific gotchas:

  • App passwords are only available once 2-Step Verification is switched on for the account.
  • Remove the spaces Google displays in the 16-character password; they are formatting only.
  • Workspace admins can restrict SMTP by IP range under *Apps → Google Workspace → Gmail → Routing*.
  • A brand new account may be blocked for the first 24 hours as an anti-abuse measure.

Microsoft 365 specifics

Microsoft 365 disables SMTP AUTH on new tenants by default. As an admin:

  1. Open the Microsoft 365 admin center and navigate to *Active users*.
  2. Select the mailbox, open *Mail*, then *Manage email apps*.
  3. Enable *Authenticated SMTP*.

Use smtp.office365.com:587 with STARTTLS and the user's full UPN.

If the tenant enforces security defaults or a conditional access policy requiring multi-factor authentication, basic SMTP AUTH will keep failing no matter what you do to the mailbox. The supported paths are a high-volume connector with IP allow-listing, or OAuth 2.0 client credentials with the SMTP.Send permission.

SendGrid, Mailgun, Postmark, SES

Transactional providers use a fixed username (often the literal string apikey) and an API key as the password. Always generate a dedicated, scoped key for each application so you can rotate without breaking other services.

Provider-specific notes worth knowing:

  • SendGrid requires the username to be exactly apikey — not your account email.
  • Mailgun uses postmaster@yourdomain and a domain-scoped password; the EU and US regions have different hostnames.
  • Postmark uses the same server token for both username and password.
  • Amazon SES SMTP credentials are *derived* from IAM credentials and are not the same as your AWS access key. Generating them in the wrong region produces a 535 that looks like a typo.

Self-hosted Postfix and Dovecot

On a self-hosted stack the authentication decision is normally delegated from Postfix to Dovecot's SASL service. When authentication fails, check in this order:

  1. /var/log/mail.log on the server — it names the exact reason, unlike the client-side reply.
  2. smtpd_sasl_auth_enable = yes in main.cf.
  3. The socket path in smtpd_sasl_path matches Dovecot's unix_listener block.
  4. Permissions on that socket allow the postfix user to read it.
  5. smtpd_tls_security_level = may (or encrypt on the submission port).

A misconfigured socket permission is the single most common cause of a self-hosted 535 with correct credentials, and nothing in the client-side error hints at it.

Security practices while you debug

Debugging tempts people into dangerous shortcuts. Avoid these:

  • Never disable certificate verification "just to test". A test that passes with verification off proves nothing about production.
  • Never paste real production credentials into a random online tool. Use a dedicated test mailbox with limited permissions.
  • Rotate any credential that appeared in a log file, a screenshot, or a support ticket.
  • Scope API keys to a single application so a rotation never causes collateral outages.

When authentication works but mail still bounces

A green check from SMTPTester means the server accepts you as a valid sender. Inbox placement is a separate layer:

  • Publish SPF, DKIM, and DMARC records for your sending domain.
  • Warm up new IPs gradually instead of sending a large batch on day one.
  • Monitor bounces and complaint rates daily.
  • Make sure the MAIL FROM domain aligns with the From header, or DMARC will fail even with valid signatures.

A repeatable debugging workflow

Save yourself the next outage by codifying the process:

  1. Reproduce against the raw server with SMTPTester and capture the full transcript.
  2. Classify the reply: connectivity, TLS, authentication, or authorisation.
  3. Change exactly one variable and re-test. Changing port and credentials together tells you nothing.
  4. Record the working configuration in your infrastructure repository, including port, encryption mode, and mechanism.
  5. Add a synthetic check that authenticates once an hour so credential expiry is detected before customers notice.

If you are seeing 5xx replies that are not on this list, paste the full server response into SMTPTester and we will surface the most likely cause in the recommendations panel.

Language and library specifics

The same authentication failure surfaces differently depending on your stack, and knowing the idiom saves time.

Node.js (Nodemailer). Set secure: false with requireTLS: true for port 587, or secure: true for 465. The most common mistake is leaving secure: true on port 587, which makes the client attempt a TLS handshake against a plaintext listener and hang until the timeout fires. Enable logger: true and debug: true while diagnosing to see the raw transcript.

Python (smtplib). Use SMTP(host, 587) followed by starttls(context=ssl.create_default_context()) and then login(). Use SMTP_SSL(host, 465) for implicit TLS. Calling login() before starttls() raises an SMTPNotSupportedError because AUTH is not advertised yet. smtp.set_debuglevel(1) prints the full conversation.

PHP (PHPMailer). Set SMTPSecure = 'tls' with Port = 587, or 'ssl' with Port = 465. SMTPDebug = 2 prints server replies. Never set SMTPOptions to disable peer verification, which is unfortunately the most-copied snippet on the internet.

Java (JavaMail). Set mail.smtp.starttls.enable=true and mail.smtp.starttls.required=true. Without the second property, JavaMail silently falls back to plaintext when the upgrade fails.

Go (net/smtp). The standard library refuses to send plaintext auth over an unencrypted connection, which trips people up on local test servers. Build the TLS connection explicitly and pass it to smtp.NewClient.

Credential rotation without downtime

Most authentication outages are self-inflicted: someone rotated a password and a forgotten service kept using the old one.

A rotation that does not cause an incident looks like this:

  1. Create the new credential alongside the old one. App passwords and API keys both support multiple active values.
  2. Deploy the new value to your secret manager.
  3. Restart or reload services so they pick it up.
  4. Watch authentication metrics for at least one full business cycle.
  5. Only then revoke the old credential.

The reason so many teams get this wrong is that they treat rotation as an edit rather than an add-then-remove. Overlapping credentials turn a risky change into a routine one.

Pair this with an inventory: a short document listing every system that authenticates to your mail server, which credential it uses, and who owns it. It takes an hour to write and prevents the "which service just started failing?" scramble entirely.

Monitoring for authentication failures

Credentials expire, get revoked, and get invalidated by policy changes that nobody told you about. The only reliable defence is a synthetic check.

Build a job that runs hourly, opens a connection to your relay, negotiates TLS, authenticates, and issues QUIT without sending a message. Alert if it fails twice in a row. This costs nothing, adds no sending volume, and turns a silent multi-hour outage into a five-minute fix.

Also alert on the failure *rate* in your application. A slow rise in 535s often precedes total failure — for example when a provider begins phasing out a mechanism and rejects a growing percentage of attempts.

Test your SMTP server now

Apply what you just learned. Free, no signup, results in seconds.

Open the tool →

Continue reading