knadh/listmonk · error
invalid e-mail address
Error message
invalid e-mail address
What it means
ErrInvalidEmail is the package-level sentinel returned by utils.SanitizeEmail when the input is not a well-formed bare email address (Go net/mail parsing; display-name components are rejected). ValidateEmail builds on it: an address is valid iff SanitizeEmail returns no error. Callers can compare with errors.Is to distinguish format errors from domain-policy rejections.
Source
Thrown at internal/utils/utils.go:13
package utils
import (
"crypto/rand"
"errors"
"net/mail"
"net/url"
"path"
"strings"
)
// ErrInvalidEmail is returned by SanitizeEmail for malformed input.
var ErrInvalidEmail = errors.New("invalid e-mail address")
// ValidateEmail reports whether s is a correctly formed bare e-mail address
// (no display name component).
func ValidateEmail(s string) bool {
_, err := SanitizeEmail(s)
return err == nil
}
// SanitizeEmail trims, lowercases, and validates s as a bare e-mail address
// (no display name) and returns the canonical form. Returns ErrInvalidEmail
// for anything `mail.ParseAddress` rejects or for input with a display name.
func SanitizeEmail(s string) (string, error) {
s = strings.ToLower(strings.TrimSpace(s))
em, err := mail.ParseAddress(s)
if err != nil || em.Address != s {
return "", ErrInvalidEmail
}
return em.Address, nilView on GitHub (pinned to 670c01717d)
Solutions
- Trim whitespace and strip display-name components, keeping only the addr-spec before validation.
- Fix the offending value to a proper user@domain.tld form.
- Use ValidateEmail as a cheap pre-check before persisting or importing.
- In your own code, compare with errors.Is(err, utils.ErrInvalidEmail) to branch on invalid format specifically.
Example fix
// before email := "John Doe <john@acme.com>" // after email := "john@acme.com"
Defensive patterns
Strategy: validation
Validate before calling
if !utils.ValidateEmail(input) {
return fmt.Errorf("%q is not a valid bare email address", input)
} Type guard
func isBareEmail(s string) bool {
if strings.Contains(s, "<") || strings.Contains(s, ">") {
return false // display-name form is rejected by SanitizeEmail
}
return utils.ValidateEmail(s)
} Try / catch
addr, err := utils.SanitizeEmail(input)
if errors.Is(err, utils.ErrInvalidEmail) {
return fmt.Errorf("invalid email format: %w", err)
} Prevention
- Validate email syntax at input time, not only at import.
- Trim whitespace and strip display names before storing addresses.
- Reuse utils.ValidateEmail rather than ad-hoc regexes.
- Compare with errors.Is(err, utils.ErrInvalidEmail) for precise branching.
When it happens
Trigger: Calling utils.SanitizeEmail (directly or via importer.SanitizeEmail / ValidateEmail) with a string failing address parsing: empty input, no '@', illegal characters, spaces, or a 'Name <addr>' display-name form.
Common situations: Importing CSVs with dirty data; accepting form input without client-side validation; storing 'John <john@x.com>' strings copied from mail clients; untrimmed newlines/tabs inside the address.
Related errors
- globals.messages.invalidFields
- campaigns.fieldInvalidFromEmail
- 'email' column not found
- subscribers.invalidEmail
- invalid SNS certificate URL: %v
AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01).
Data as JSON: /api/errors/7a094f4d392ea80f.
Report an issue: GitHub.