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
- Provide the SMTP account password in the smtpPassword field of the request.
- Check that secret injection (env var / template) actually populated the field before submission.
- 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
- Bind the password field in the frontend form and block submission while empty
- Verify secret injection (env/template) actually populated the value
- Treat credentials as required fields in form-level validation before the API call
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
- SMTP port must be between 1 and 65535
- at least one recipient is required
- hostname format is incorrect
- port must be between 1-65535
- IPv4 network format is incorrect, please use CIDR format (e.
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/8ce329b45b34e9fb.
Report an issue: GitHub.