Billionmail/BillionMail · error
Failed to write DKIM public key: %v
Error message
Failed to write DKIM public key: %v
What it means
After key generation, the rspamadm output (public key text) is written to <selector>.pub on the host via public.WriteFile. This error wraps that write failure. The private key exists in the Rspamd volume but the public key file needed to build the DKIM DNS record is missing.
Source
Thrown at core/internal/service/domains/domains.go:563
}
defer dk.Close()
// Generate new keys if they don't exist
if !public.FileExists(dkimPriPath) || !public.FileExists(dkimPubPath) {
mutex.Lock()
defer mutex.Unlock()
var res *v2.ExecResult
res, err = dk.ExecCommandByName(context.Background(), consts.SERVICES.Rspamd, []string{"rspamadm", "dkim_keygen", "-s", selector, "-b", fmt.Sprintf("%d", keySize), "-d", domain, "-k", fmt.Sprintf("/var/lib/rspamd/dkim/%s/%s.private", domain, selector)}, "root")
if err != nil {
err = fmt.Errorf("Failed to generate DKIM key pair: %v", err)
return
}
if res != nil {
_, err = public.WriteFile(dkimPubPath, res.Output)
if err != nil {
err = fmt.Errorf("Failed to write DKIM public key: %v", err)
return
}
}
// update dkim private key file permission to 0644
err = os.Chmod(dkimPriPath, 0644)
if err != nil {
err = fmt.Errorf("Failed to change DKIM private key permissions: %v", err)
return
}
// Skip DKIM signing config for relay-mapped domains — relay provider signs
relayDomains, relayErr := GetRelayDomains(context.Background())
if relayErr != nil {
g.Log().Warning(context.Background(), "Failed to check relay domains for DKIM signing:", relayErr)
relayDomains = make(map[string]bool)
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Ensure the DKIM directory exists on the host (os.MkdirAll(dkimPath, 0755) before writing) and check the wrapped permission/disk error
- Verify rspamadm output was non-empty; re-run key generation if res.Output is empty
- Fix ownership/permissions on the dkim volume mount
- Re-run GetDKIMRecord to regenerate both keys if the pub file is corrupt
Example fix
// before
if res != nil {
_, err = public.WriteFile(dkimPubPath, res.Output)
if err != nil { err = fmt.Errorf("Failed to write DKIM public key: %v", err); return }
}
// after
if res == nil || len(strings.TrimSpace(res.Output)) == 0 {
err = fmt.Errorf("rspamadm dkim_keygen produced no output")
return
}
if err = os.MkdirAll(dkimPath, 0755); err != nil { return }
if _, err = public.WriteFile(dkimPubPath, res.Output); err != nil {
err = fmt.Errorf("Failed to write DKIM public key to %s: %v", dkimPubPath, err)
return
} Defensive patterns
Strategy: validation
Validate before calling
if err := os.MkdirAll(dkimPath, 0755); err != nil { return fmt.Errorf("cannot create dkim dir: %v", err) }
if err := unix.Access(dkimPath, unix.W_OK); err != nil { return fmt.Errorf("dkim dir not writable: %v", err) } Try / catch
if _, err := public.WriteFile(dkimPubPath, res.Output); err != nil {
return fmt.Errorf("Failed to write DKIM public key %s: %v", dkimPubPath, err) // includes path context
} Prevention
- Create the DKIM directory before keygen, not after
- Match volume ownership between rspamd container and host process
- Check free disk space before key generation
- Validate keygen output is non-empty before writing
When it happens
Trigger: getDKIMRecordWithKeySize after successful dkim_keygen when public.WriteFile(dkimPubPath, res.Output) fails — dkim directory missing on host, permission denied, disk full, or res.Output empty because the exec result carried no output.
Common situations: Host-side dkimPath not created before WriteFile (missing os.MkdirAll); volume permission mismatch between rspamd container user and host; res==nil or empty output path silently producing a bad/empty pub file if not guarded (here guarded by res != nil but not by empty output).
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Failed to read DKIM sign config: %v
- Failed to write DKIM sign config: %v
- Cannot read DKIM public key: %v
- failed to write DKIM signing config: %v
- Failed to generate DKIM key pair: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/7edf780bdabf978d.
Report an issue: GitHub.