Billionmail/BillionMail · warning
Failed to parse DKIM record: %v
Error message
Failed to parse DKIM record: %v
What it means
Thrown when the regex extracting quoted segments from the DKIM TXT record (grex: `"([^"]+)"`) fails to compile/match due to a regex engine error. This happens while normalizing an existing multi-line DKIM record read from rspamd back into a single-line record.
Source
Thrown at core/internal/service/domains/domains.go:665
}
// Format DKIM record
// Expected format is a pre-formatted TXT record value like "v=DKIM1; k=rsa; p=MIIBIjANBg..."
dkimRecord := strings.TrimSpace(dkimPub)
// If the raw public key is read, format it into DNS TXT record format
if !strings.Contains(dkimRecord, "v=DKIM1") && !strings.Contains(dkimRecord, "k=rsa") && !strings.Contains(dkimRecord, "p=") {
// Remove possible header/footer markers and newlines
dkimRecord = strings.ReplaceAll(dkimRecord, "-----BEGIN PUBLIC KEY-----", "")
dkimRecord = strings.ReplaceAll(dkimRecord, "-----END PUBLIC KEY-----", "")
dkimRecord = strings.ReplaceAll(dkimRecord, "\n", "")
dkimRecord = strings.TrimSpace(dkimRecord)
dkimRecord = fmt.Sprintf("v=DKIM1; k=rsa; p=%s", dkimRecord)
} else {
var ms [][]string
ms, err = gregex.MatchAllString(`"([^"\r\n]+)"`, dkimRecord)
if err != nil {
err = fmt.Errorf("Failed to parse DKIM record: %v", err)
return
}
if len(ms) < 2 {
err = fmt.Errorf("Invalid DKIM record format")
return
}
s := ""
for _, v := range ms {
if len(v) < 2 {
continue
}
s += v[1]
}
dkimRecord = s
}View on GitHub (pinned to fc36c76c05)
Solutions
- Inspect the DKIM key/record file content for corruption and regenerate keys via RepairDKIMSigningConfig
- Verify the content is plain ASCII with standard quoted record sections
- Upgrade/align GoFrame version if gregex behavior changed unexpectedly
- Add a pre-read sanity check that the file content looks like a DKIM record before regex parsing
Example fix
// before
ms, err = gregex.MatchAllString(`"([^
]+)"`, dkimRecord)
// after: guard with a quick sanity check
if !strings.Contains(dkimRecord, "v=DKIM1") && !strings.Contains(dkimRecord, "p=") {
return fmt.Errorf("file does not look like a DKIM record; regenerate keys")
}
ms, err = gregex.MatchAllString(`"([^
]+)"`, dkimRecord) Defensive patterns
Strategy: validation
Validate before calling
raw, _ := os.ReadFile(dkimPubPath)
if utf8.Valid(raw) && (strings.Contains(string(raw), "v=DKIM1") || strings.Contains(string(raw), "p=")) {
// safe to regex-parse
} Type guard
func looksLikeDKIMRecord(s string) bool {
return strings.Contains(s, "v=DKIM1") || strings.Contains(s, "p=")
} Try / catch
ms, err := gregex.MatchAllString(`"([^
]+)"`, dkimRecord)
if err != nil {
log.Printf("DKIM record regex failure: %v — content may be corrupt; regenerate keys", err)
return err
} Prevention
- Never hand-edit DKIM key/record files; always use RepairDKIMSigningConfig
- Validate file contents are plain ASCII after any import/restore
- Pin GoFrame versions and test gregex behavior on upgrade
When it happens
Trigger: gregex.MatchAllString returns an error on the raw dkimRecord content — effectively only on malformed regex invocation or pathological input handled by the engine; normal empty/no-match input yields len(ms)<2 (error 305) instead.
Common situations: Corrupted or binary content in the DKIM key file being parsed as a record, extremely long lines stressing the regex engine, or a GoFrame/gregex version regression in MatchAllString behavior.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid DKIM record format
- error reading CSV file: %v
- failed to read CSV headers: %v
- failed to parse alert settings: %v
- failed to query relay domain mappings: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/11932bf1b6d19663.
Report an issue: GitHub.