Billionmail/BillionMail · error
SMTP auth: %w
Error message
SMTP auth: %w
What it means
This error is returned when client.Auth(smtp.PlainAuth(...)) fails during connectWithSSL — the server rejected authentication with a 5xx reply (e.g. 535 authentication failed) or the AUTH mechanism is unsupported. The client is closed before returning so the connection is not leaked. The wrapped error carries the SMTP server response text, which names the exact cause.
Source
Thrown at core/internal/service/mail_service/sending.go:226
conn, err := tls.Dial("tcp", net.JoinHostPort(e.Host, e.Port), &tls.Config{
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: true,
ServerName: e.SNI,
})
if err != nil {
return fmt.Errorf("TLS dial: %w", err)
}
client, err := smtp.NewClient(conn, e.Host)
if err != nil {
conn.Close()
return fmt.Errorf("new SMTP client: %w", err)
}
auth := smtp.PlainAuth("", e.UserName, e.Password, e.Host)
if err = client.Auth(auth); err != nil {
client.Close()
return fmt.Errorf("SMTP auth: %w", err)
}
e.client = client
return nil
}
// connectPlain establishes a plain SMTP connection
func (e *EmailSender) connectPlain() error {
client, err := smtp.Dial(net.JoinHostPort(e.Host, e.Port))
if err != nil {
return fmt.Errorf("SMTP dial: %w", err)
}
// Check if STARTTLS is needed
if e.Port == "587" {
if err = client.StartTLS(&tls.Config{
MinVersion: tls.VersionTLS12,View on GitHub (pinned to fc36c76c05)
Solutions
- Read the wrapped server reply (e.g. '535 5.7.8 Bad credentials') and fix the credentials in the sender configuration.
- Use the full email address as the username; for Gmail/Yahoo use an app-specific password.
- Check the server's advertised AUTH mechanisms in the EHLO response (openssl s_client -connect host:465 or swaks --auth) and match the mechanism.
- If the server requires LOGIN auth, implement/switch to an smtp.Auth that speaks LOGIN (the codebase's customAuth does this for port 25; adapt as needed).
Example fix
// before
auth := smtp.PlainAuth("", e.UserName, e.Password, e.Host)
if err = client.Auth(auth); err != nil {
client.Close()
return fmt.Errorf("SMTP auth: %w", err)
}
// after
auth := smtp.PlainAuth("", e.UserName, e.Password, e.Host)
if err = client.Auth(auth); err != nil {
client.Close()
if strings.Contains(err.Error(), "535") {
return fmt.Errorf("SMTP auth: invalid credentials for %s (check password/app-password): %w", e.Host, err)
}
return fmt.Errorf("SMTP auth: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
func validateCredentials(user, pass, host, port string) error {
conn, err := smtp.Dial(net.JoinHostPort(host, port))
if err != nil {
return err
}
defer conn.Close()
if err := conn.StartTLS(&tls.Config{ServerName: host}); err != nil {
return err
}
ok, mechs := conn.Extension("AUTH")
if !ok {
return fmt.Errorf("server %s does not advertise AUTH", host)
}
_ = mechs // check it includes PLAIN/LOGIN before configuring
return conn.Auth(smtp.PlainAuth("", user, pass, host))
} Type guard
func isAuthRejected(err error) bool {
var protoErr *textproto.Error
return errors.As(err, &protoErr) && protoErr.Code >= 500 && protoErr.Code < 600
} Try / catch
if err := sender.Send(msg, rcpts); err != nil {
if strings.Contains(err.Error(), "SMTP auth") {
// do not blind-retry: credentials are wrong; surface to config UI
return ErrBadCredentials
}
} Prevention
- Store and test credentials at config time, not first send.
- Use the full email address as the SMTP username; use app passwords for Gmail/Yahoo.
- Confirm the server's AUTH mechanisms include PLAIN before relying on smtp.PlainAuth.
When it happens
Trigger: Connect() on a secure (implicit TLS) EmailSender where e.UserName/e.Password are wrong, the server does not advertise PLAIN auth, or the server requires a different mechanism (LOGIN, XOAUTH2, CRAM-MD5).
Common situations: Expired or revoked SMTP password / app password (Gmail requires app passwords with 2FA); username must be the full email address but only the local part was configured; provider disabled basic auth entirely (e.g. Microsoft deprecating basic AUTH); account locked or sending IP blocked.
Related errors
- SMTP password is required
- TLS dial: %w
- new SMTP client: %w
- SMTP STARTTLS: %w
- Invalid username or password
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/ee5905df09a29ecc.
Report an issue: GitHub.