SMTPLIB

smtplib Username and Password Not Accepted

Python smtplib "Username and Password not accepted" (SMTP 535 5.7.8) means the server rejected SMTP.login(). Fix it with a Gmail App Password or OAuth 2.0.

Updated Jul 1, 2026

The short answer

"Username and Password not accepted" is the message Python's smtplib raises as SMTPAuthenticationError when an SMTP server rejects your SMTP.login() credentials — typically Gmail returning "535-5.7.8". It almost never means a typo: Gmail stopped accepting regular passwords from scripts, so you must authenticate with a 16-character App Password (2-Step Verification required) or OAuth 2.0.

This message comes from Python's smtplib. When SMTP.login(user, password) fails, smtplib raises smtplib.SMTPAuthenticationError, and the text you see is the server's reply echoed back. With Gmail the full reply is almost always:

smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. For more information, go to\n5.7.8 https://support.google.com/mail/?p=BadCredentials ...')

The 535 reply code and the 5.7.8 enhanced status code ("Authentication credentials invalid") are both defined by RFC 4954, the SMTP authentication extension. RFC 3463 provides the underlying enhanced-status-code framework (the class.subject.detail structure and the X.7 "Security or Policy" subject, covering X.7.0 through X.7.7), but the specific .8 detail for invalid credentials comes from RFC 4954. It is a permanent failure — retrying with the same credentials will not help.

What causes "Username and Password not accepted"?

The server received your AUTH attempt and explicitly rejected the credentials. With Gmail and Google Workspace, the dominant cause today is not a typo — it is that Google no longer accepts your normal account password from scripts:

  • Google removed password-based ("less secure app") sign-in. Personal Gmail lost it on May 30, 2022; Google Workspace accounts lost it by 2025. Your real Google password will be rejected here regardless of whether it is correct. (Note: the old myaccount.google.com/lesssecureapps toggle no longer exists — ignore any guide that tells you to enable it.)
  • No App Password generated. With 2-Step Verification on, third-party SMTP clients must use a 16-character App Password, not your login password.
  • Wrong username form. Gmail requires the full address (you@gmail.com), not the local part.
  • Spaces or quoting in the password string. App Passwords are displayed in four space-separated groups; the spaces are cosmetic. Pasting them verbatim (or leaving a trailing newline) breaks AUTH.
  • OAuth path misused. If you intend to use XOAUTH2, passing the raw token to login() instead of SMTP.auth() with a proper auth object will fail.
  • Account/policy block. A suspended account, or a Workspace admin policy disabling SMTP AUTH, returns the same 535.

How do I fix "Username and Password not accepted" with Gmail?

1. Turn on 2-Step Verification for the Google account at myaccount.google.com/security. App Passwords are unavailable without it.

2. Generate an App Password at myaccount.google.com/apppasswords. Google shows a 16-character code in four groups.

3. Use the App Password in login() — your full email as the username, the 16 characters with the spaces removed:

import smtplib, ssl
context = ssl.create_default_context()
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls(context=context)
server.login("you@gmail.com", "abcdefghijklmnop") # App Password, no spaces
server.sendmail("you@gmail.com", "to@example.com", "Subject: hi\n\nbody")

Port 587 (STARTTLS) and port 465 (implicit TLS via smtplib.SMTP_SSL) are both valid per RFC 8314 — pick one and match the connection class. Do not call starttls() on a 465/SMTP_SSL connection.

4. Prefer OAuth 2.0 for production. App Passwords are a stopgap; Google recommends OAuth 2.0 (XOAUTH2) for server applications. Build the SASL XOAUTH2 string and authenticate with server.auth("XOAUTH2", lambda: auth_string) rather than login().

Is this a Gmail-specific error?

No. Any SMTP server can return 535 / 5.7.8, and smtplib will surface it the same way. For SendGrid the username must be the literal string apikey and the password your API key; for Amazon SES, your raw AWS access key/secret cannot be pasted directly into an SMTP password field — use the SMTP credentials generated in the SES console; for Mailgun use the SMTP username and password from the domain's settings. If you are not on Gmail, confirm you are using the provider's SMTP credentials, which are frequently distinct from your dashboard login or API key.

If you route mail through Courier, you supply provider SMTP credentials once in the Courier dashboard rather than embedding them in smtplib, which removes this class of credential-handling error from your application code.

FAQ

Common questions

Because Google no longer accepts regular account passwords from scripts or third-party SMTP clients. Even a perfectly correct password is rejected. Enable 2-Step Verification and authenticate with a 16-character App Password, or use OAuth 2.0. The old 'less secure apps' toggle was removed in 2022 and is not an option.

One API, every provider

Stop debugging raw provider errors

Courier connects to your email, SMS, and push providers, handles retries and failover, and surfaces delivery errors in plain language.

Reply-code definitions per RFC 4954 (5.7.8) / RFC 3463 (X.7 framework). Last reviewed Jul 1, 2026. Courier is not affiliated with third-party providers; error behavior may vary by implementation.