Billionmail/BillionMail · error

SMTP password is required

Error message

SMTP password is required

What it means

validateAlertSettings requires a non-empty SMTPPassword for blacklist alert email delivery. The password is used to authenticate against the SMTP server when the test email is sent; an empty string is treated as missing credentials.

Source

Thrown at core/internal/controller/settings/settings_v1_set_blacklist_alert_settings.go:84

func validateAlertSettings(settings *v1.SetBlacklistAlertSettingsReq) error {
	if settings.SenderEmail == "" {
		return fmt.Errorf("sender email is required")
	}

	if !strings.Contains(settings.SenderEmail, "@") {
		return fmt.Errorf("invalid sender email format")
	}

	if settings.SMTPServer == "" {
		return fmt.Errorf("SMTP server is required")
	}

	if settings.SMTPPort < 1 || settings.SMTPPort > 65535 {
		return fmt.Errorf("SMTP port must be between 1 and 65535")
	}

	if settings.SMTPPassword == "" {
		return fmt.Errorf("SMTP password is required")
	}

	if len(settings.RecipientList) == 0 {
		return fmt.Errorf("at least one recipient is required")
	}

	for _, recipient := range settings.RecipientList {
		if !strings.Contains(recipient, "@") {
			return fmt.Errorf("invalid recipient email format: %s", recipient)
		}
	}

	return nil
}

func testSMTPConnectionWithRelay(ctx context.Context, settings *v1.SetBlacklistAlertSettingsReq) error {
	//g.Log().Infof(ctx, "Testing SMTP connection to %s:%d", settings.SMTPServer, settings.SMTPPort)

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Provide the SMTP account password in the smtpPassword field of the request.
  2. Check that secret injection (env var / template) actually populated the field before submission.
  3. If using a local relay that needs no auth, set a placeholder or extend the validator to skip the check when SMTPServer points at the internal mail service.

Example fix

// before
settings.SMTPPassword = os.Getenv("SMTP_PASSWORD") // empty if unset
// after
pwd := os.Getenv("SMTP_PASSWORD")
if pwd == "" { return errors.New("SMTP_PASSWORD env var not set") }
settings.SMTPPassword = pwd
Defensive patterns

Strategy: validation

Validate before calling

if (!payload.smtpPassword || payload.smtpPassword.trim() === '') {
  throw new Error('smtpPassword is required before saving alert settings')
}

Type guard

function hasPassword(s: { smtpPassword?: string }): s is { smtpPassword: string } {
  return typeof s.smtpPassword === 'string' && s.smtpPassword.length > 0
}

Try / catch

try {
  await api.setBlacklistAlertSettings(payload)
} catch (e) {
  if (String(e).includes('SMTP password is required')) {
    showFormError('passwordField', 'SMTP password is required')
  }
}

Prevention

When it happens

Trigger: Calling SetBlacklistAlertSettings with SMTPPassword empty or omitted in the request payload.

Common situations: Frontend form does not bind the password field; secret stripped by an env templating step that left it blank; admin assumes the mail service relay needs no password but this code path requires one.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/8ce329b45b34e9fb. Report an issue: GitHub.