{"record":{"id":"de2c32aab82ecb7e","repo":"knadh/listmonk","slug":"subscribers-invalidemail","errorCode":null,"errorMessage":"subscribers.invalidEmail","messagePattern":"subscribers\\.invalidEmail","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/subimporter/importer.go","lineNumber":614,"sourceCode":"\t\tim.Unlock()\n\n\t\treturn\n\t}\n\n\tselect {\n\tcase im.stop <- true:\n\t\tim.setStatus(StatusStopping)\n\tdefault:\n\t}\n}\n\n// SanitizeEmail validates and sanitizes an e-mail string and returns the\n// canonical (lowercased, trimmed) address. Domain allowlist/blocklist rules\n// are enforced on top of the bare-address validation in utils.SanitizeEmail.\nfunc (im *Importer) SanitizeEmail(email string) (string, error) {\n\taddr, err := utils.SanitizeEmail(email)\n\tif err != nil {\n\t\treturn \"\", errors.New(im.i18n.T(\"subscribers.invalidEmail\"))\n\t}\n\n\t// Check if the e-mail's domain is blocklisted. The e-mail domain and blocklist config\n\t// are always lowercase.\n\tif im.hasAllowlist || im.hasBlocklist {\n\t\td := strings.Split(addr, \"@\")\n\t\tif len(d) != 2 {\n\t\t\treturn addr, nil\n\t\t}\n\n\t\tdomain := d[1]\n\n\t\t// If there's an allowlist, check if the domain is in it. Checking blocklist after that is moot.\n\t\tif im.hasAllowlist {\n\t\t\tif !im.checkInList(domain, im.hasAllowlistWildcards, im.domainAllowlist) {\n\t\t\t\treturn \"\", errors.New(im.i18n.T(\"subscribers.domainBlocklisted\"))\n\t\t\t}\n\t\t} else if im.hasBlocklist {","sourceCodeStart":596,"sourceCodeEnd":632,"githubUrl":"https://github.com/knadh/listmonk/blob/670c01717d48647093335cc23a6be6f4b79c3b6b/internal/subimporter/importer.go#L596-L632","documentation":"Importer.SanitizeEmail wraps utils.SanitizeEmail; when bare-address validation fails (malformed email), it replaces the low-level error with the i18n message 'subscribers.invalidEmail' so import errors are localized. It is thrown per-row during subscriber import when the email value cannot be parsed as a valid address.","triggerScenarios":"ValidateFields calls SanitizeEmail on each imported row and the email string fails utils.SanitizeEmail — empty string, missing '@', invalid characters, unbalanced quotes, or invalid domain format.","commonSituations":"Dirty third-party lists with values like 'john(at)acme.com', trailing spaces/commas, concatenated fields, or Excel-mangled emails; also rows where column shift put a name in the email cell.","solutions":["Correct or remove rows with malformed email values in the CSV before importing.","Pre-validate the file with a script using the same address syntax check (e.g. Go net/mail ParseAddress).","Trim whitespace and strip stray characters (commas, quotes) from the email column.","If valid emails are rejected, verify the input encoding (BOM, smart quotes) isn't corrupting values."],"exampleFix":"// before\nemail\njohn acme.com\n// after\nemail\njohn@acme.com","handlingStrategy":"validation","validationCode":"email := strings.TrimSpace(row.Email)\nif email == \"\" || len(email) > 1000 {\n    return fmt.Errorf(\"row %d: empty or oversized email\", i)\n}\nif _, err := mail.ParseAddress(email); err != nil {\n    return fmt.Errorf(\"row %d: malformed email %q\", i, email)\n}","typeGuard":"func isValidEmail(s string) bool {\n    _, err := mail.ParseAddress(strings.TrimSpace(s))\n    return err == nil && !strings.Contains(s, \" \")\n}","tryCatchPattern":"em, err := importer.SanitizeEmail(email)\nif err != nil {\n    log.Printf(\"skipping row: %v\", err) // localized 'subscribers.invalidEmail'\n    continue\n}","preventionTips":["Trim and normalize the email column before import.","Reject display-name forms ('Name <a@b.c>') at data entry.","Deduplicate and syntax-check lists from third parties before import.","Use ValidateEmail for pre-screening files client-side."],"tags":["email","validation","import","i18n"],"backgroundTag":"invalid-email-format","analyzedSha":"670c01717d48647093335cc23a6be6f4b79c3b6b","analyzedAt":"2026-09-01T03:39:35.452Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}