knadh/listmonk · error
'email' column not found
Error message
'email' column not found
What it means
LoadCSV parses a subscriber import CSV and requires an 'email' column to map records to subscribers. Before importing any rows it maps CSV headers to known field keys via mapCSVHeaders and checks that an 'email' header exists. If the header is missing, the import is aborted immediately with this error because no subscriber could be created or identified.
Source
Thrown at internal/subimporter/importer.go:509
s.im.Unlock()
// Rewind, now that we've done a linecount on the same handler.
_, _ = f.Seek(0, 0)
rd := csv.NewReader(f)
rd.Comma = delim
// Read the header.
csvHdr, err := rd.Read()
if err != nil {
s.log.Printf("error reading header from '%s': '%v'", srcPath, err)
return err
}
hdrKeys := s.mapCSVHeaders(csvHdr, csvHeaders)
// email is a required header.
if _, ok := hdrKeys["email"]; !ok {
s.log.Printf("'email' column not found in '%s'", srcPath)
return errors.New("'email' column not found")
}
var (
lnHdr = len(hdrKeys)
i = 0
)
for {
i++
// Check for the stop signal.
select {
case <-s.im.stop:
failed = false
close(s.subQueue)
s.log.Println("stop request received")
return nil
default:
}View on GitHub (pinned to 670c01717d)
Solutions
- Add a column named exactly 'email' to the CSV header row (check for typos, extra spaces, or a BOM on the first cell).
- Re-export the CSV ensuring the header row is included and the email column is labeled 'email'.
- If the source system uses a different label, rename the column in the file or preprocess it before upload.
- Open the first line of the file in a text editor to confirm a header row exists at all.
Example fix
// before name,company John,Acme // after email,name,company john@acme.com,John,Acme
Defensive patterns
Strategy: validation
Validate before calling
f, _ := os.Open(srcPath)
r := csv.NewReader(f)
hdr, err := r.Read()
if err != nil { return err }
found := false
for _, h := range hdr {
if strings.EqualFold(strings.TrimSpace(h), "email") { found = true; break }
}
if !found {
return fmt.Errorf("CSV %s has no 'email' header column", srcPath)
} Prevention
- Always include a header row with an exact 'email' column.
- Export templates from listmonk itself to guarantee compatible headers.
- Strip BOM/whitespace from the first line before upload.
- Lint import files in CI with a schema check requiring 'email'.
When it happens
Trigger: Calling LoadCSV (or the admin import API) with a CSV file whose header row lacks an 'email' column — e.g. headers like 'mail', 'e-mail', 'Email Address', or a file with no header row at all.
Common situations: Exporting subscribers from another ESP with differently named columns; uploading a data-only CSV after someone deleted the header line; case/whitespace mismatches or a BOM on the first cell that break header matching.
Related errors
- subscribers.invalidEmail
- invalid e-mail address
- invalid SNS certificate URL: %v
- globals.messages.invalidFields
- campaigns.fieldInvalidFromEmail
AI-assisted analysis of knadh/listmonk@670c01717d (2026-09-01).
Data as JSON: /api/errors/eb26857838e1f8a7.
Report an issue: GitHub.