Billionmail/BillionMail · error
failed to write postfix master config: %v
Error message
failed to write postfix master config: %v
What it means
Raised in SetPostfixMasterSSL when os.WriteFile fails to persist the edited Postfix master.cf (c.PostfixMasterConf path) after the smtpd_tls_auth_only/smtpd_tls_wrappermode substitutions succeeded. Typical causes: permission denial on the Postfix config path or a read-only filesystem; the SSL enable flow aborts before service restart.
Source
Thrown at core/internal/service/mail_service/certificate.go:181
if err != nil {
return fmt.Errorf("failed to read postfix master config: %v", err)
}
content, err = gregex.ReplaceString(`\n*#\s*-o\s+smtpd_tls_auth_only=yes`, "\n -o smtpd_tls_auth_only=yes", content)
if err != nil {
return fmt.Errorf("failed to update postfix master config: %v", err)
}
content, err = gregex.ReplaceString(`\n*#\s*-o\s+smtpd_tls_wrappermode=yes`, "\\n -o smtpd_tls_wrappermode=yes", content)
if err != nil {
return fmt.Errorf("failed to update postfix master config: %v", err)
}
// Update Postfix Master configuration
if err := os.WriteFile(c.PostfixMasterConf, []byte(content), 0755); err != nil {
return fmt.Errorf("failed to write postfix master config: %v", err)
}
return nil
}
// SetDovecotSSL configures SSL certificate for Dovecot
func (c *Certificate) SetDovecotSSL(csrPem, keyPem string) error {
// Validate certificate data
if err := c.verifyCertificate(csrPem, keyPem); err != nil {
return err
}
// Update Dovecot configuration
if err := c.updateDovecotConfig(csrPem, keyPem); err != nil {
return err
}
// Restart Dovecot serviceView on GitHub (pinned to fc36c76c05)
Solutions
- Run the service with privileges to write master.cf (root or CAP_DAC_OVERRIDE in container)
- Ensure the postfix config volume is mounted read-write
- Check filesystem free space and mount flags (ro vs rw)
- Consider writing atomically (temp file + rename) and matching mode 0644 typical for master.cf instead of 0755
Defensive patterns
Strategy: validation
Validate before calling
cfPath := consts.POSTFIX_MASTER_CONF
if err := os.MkdirAll(filepath.Dir(cfPath), 0755); err != nil { return err }
test, err := os.OpenFile(cfPath, os.O_WRONLY, 0)
if err != nil {
return fmt.Errorf("cannot write %s: %w (need root or rw mount)", cfPath, err)
}
test.Close() Try / catch
if err := certService.SetPostfixMasterSSL(); err != nil {
if strings.Contains(err.Error(), "failed to write postfix master config") {
if isReadOnly(strings Dir(cfPath)) { remountOrRelaunchWithWriteAccess() }
return err
}
return err
} Prevention
- Run the TLS automation as root or with a rw-mounted /etc/postfix
- Check df/disk space before config writes
- Write atomically (temp file + os.Rename) and use mode 0644
When it happens
Trigger: os.WriteFile to c.PostfixMasterConf fails: read-only filesystem, missing directory, or insufficient permissions (app not running as root).
Common situations: App container without write access to /etc/postfix; master.cf mounted read-only in Docker; disk full on the config volume.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- failed to save private key: %v
- failed to read postfix master config: %v
- failed to read postfix config: %v
- failed to write certificate file: %v
- failed to write key file: %v
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/75414c00e8f17f48.
Report an issue: GitHub.