Billionmail/BillionMail · error
failed to read postfix config: %v
Error message
failed to read postfix config: %v
What it means
updatePostfixConfig reads Postfix main.cf (consts.POSTFIX_MAIN_CONF) with os.ReadFile before rewriting the smtpd_tls_cert_file/key_file lines. This error wraps the read failure and is raised by SetSSL and SetPostfixSSL when main.cf is missing or unreadable.
Source
Thrown at core/internal/service/mail_service/certificate.go:232
return fmt.Errorf("private key data is empty")
}
// Validate certificate
cInfo := acme.GetCertInfo(csrPem)
if cInfo.Endtime == 0 {
return fmt.Errorf("certificate is invalid")
}
return nil
}
// updatePostfixConfig updates Postfix configuration with new certificate
func (c *Certificate) updatePostfixConfig(csrPem, keyPem string) error {
mainCf := public.AbsPath(consts.POSTFIX_MAIN_CONF)
content, err := os.ReadFile(mainCf)
if err != nil {
return fmt.Errorf("failed to read postfix config: %v", err)
}
// Write certificate and key to files
certPath := public.AbsPath(filepath.Join(consts.SSL_PATH, "postfix.crt"))
keyPath := public.AbsPath(filepath.Join(consts.SSL_PATH, "postfix.key"))
if err := os.WriteFile(certPath, []byte(csrPem), 0755); err != nil {
return fmt.Errorf("failed to write certificate file: %v", err)
}
if err := os.WriteFile(keyPath, []byte(keyPem), 0755); err != nil {
return fmt.Errorf("failed to write key file: %v", err)
}
// Update SSL certificate configuration
config := string(content)
config = c.updateConfigLine(config, "smtpd_tls_key_file", keyPath)
config = c.updateConfigLine(config, "smtpd_tls_cert_file", certPath)View on GitHub (pinned to fc36c76c05)
Solutions
- Verify the main.cf path (postconf -h config_directory) and correct consts.POSTFIX_MAIN_CONF or the deployment mount
- Install postfix / initialize the mail server before applying certificates
- Grant the process read access to main.cf
- Log the wrapped error to identify whether it is ENOENT or EACCES
Defensive patterns
Strategy: validation
Validate before calling
mainCf := public.AbsPath(consts.POSTFIX_MAIN_CONF)
if _, err := os.Stat(mainCf); err != nil {
return fmt.Errorf("postfix main.cf missing at %s — install/initialize postfix first: %w", mainCf, err)
} Try / catch
if err := certService.SetSSL(csrPem, keyPem); err != nil {
if strings.Contains(err.Error(), "failed to read postfix config") {
log.Errorf("main.cf unreadable: %s", err)
return ErrPostfixNotInstalled
}
return err
} Prevention
- Run mail-server initialization before certificate automation
- Keep consts.POSTFIX_MAIN_CONF aligned with the deployed postfix layout
- Ensure the app user can read /etc/postfix/main.cf in every environment
When it happens
Trigger: Calling SetSSL or SetPostfixSSL on a machine where AbsPath(consts.POSTFIX_MAIN_CONF) does not exist or cannot be read by the process user.
Common situations: Postfix not installed (fresh container/mail-server not initialized); custom postfix chroot/config directory; permission mismatch between the app user and /etc/postfix/main.cf.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- failed to read postfix master config: %v
- failed to update postfix master config: %v
- failed to write postfix master config: %v
- failed to write postfix config: %v
- failed to update SNI map: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/32f8b9832afb1679.
Report an issue: GitHub.