Billionmail/BillionMail · error

failed to update postfix master config: %v

Error message

failed to update postfix master config: %v

What it means

After reading master.cf, SetPostfixMasterSSL uses gregex.ReplaceString to uncomment '-o smtpd_tls_auth_only=yes'. This error is returned when the regex engine itself fails (invalid pattern or replacement), before any write occurs.

Source

Thrown at core/internal/service/mail_service/certificate.go:170

	if err := c.restartPostfix(); err != nil {
		return err
	}

	return nil
}

// SetPostfixMasterSSL enables SSL for Postfix Master
func (c *Certificate) SetPostfixMasterSSL() error {
	// Read Postfix Master configuration
	content, err := public.ReadFile(consts.POSTFIX_MASTER_CONF)
	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 {

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Upgrade/verify the GoFrame gregex dependency version
  2. Replace the two regex calls with plain strings.Replace for these fixed strings, eliminating regex errors entirely
  3. Reproduce with a small test calling gregex.ReplaceString with the same pattern

Example fix

// before
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)
}
// after
content = strings.ReplaceAll(content, "#  -o smtpd_tls_auth_only=yes", "  -o smtpd_tls_auth_only=yes")
Defensive patterns

Strategy: try-catch

Try / catch

if err := certService.SetPostfixMasterSSL(); err != nil {
    if strings.Contains(err.Error(), "failed to update postfix master config") {
        log.Errorf("regex rewrite of master.cf failed: %s", err)
        return fmt.Errorf("could not enable smtpd_tls_auth_only; pin/upgrade gregex: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: gregex.ReplaceString returning an error on the pattern `\n*#\s+-o\s+smtpd_tls_auth_only=yes` — practically rare since the pattern is static; typically only seen if the GoFrame regex dependency misbehaves.

Common situations: Corrupted or incompatible gregex/GoFrame version after an upgrade; panic-level bug surfaced as error from the regex call.

Related errors


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/6601aff70d2ccb6b. Report an issue: GitHub.