{"record":{"id":"6601aff70d2ccb6b","repo":"Billionmail/BillionMail","slug":"failed-to-update-postfix-master-config-v","errorCode":null,"errorMessage":"failed to update postfix master config: %v","messagePattern":"failed to update postfix master config: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/mail_service/certificate.go","lineNumber":170,"sourceCode":"\tif err := c.restartPostfix(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// SetPostfixMasterSSL enables SSL for Postfix Master\nfunc (c *Certificate) SetPostfixMasterSSL() error {\n\t// Read Postfix Master configuration\n\tcontent, err := public.ReadFile(consts.POSTFIX_MASTER_CONF)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read postfix master config: %v\", err)\n\t}\n\n\tcontent, err = gregex.ReplaceString(`\\n*#\\s*-o\\s+smtpd_tls_auth_only=yes`, \"\\n  -o smtpd_tls_auth_only=yes\", content)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to update postfix master config: %v\", err)\n\t}\n\n\tcontent, err = gregex.ReplaceString(`\\n*#\\s*-o\\s+smtpd_tls_wrappermode=yes`, \"\\\\n  -o smtpd_tls_wrappermode=yes\", content)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to update postfix master config: %v\", err)\n\t}\n\n\t// Update Postfix Master configuration\n\tif err := os.WriteFile(c.PostfixMasterConf, []byte(content), 0755); err != nil {\n\t\treturn fmt.Errorf(\"failed to write postfix master config: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// SetDovecotSSL configures SSL certificate for Dovecot\nfunc (c *Certificate) SetDovecotSSL(csrPem, keyPem string) error {","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_service/certificate.go#L152-L188","documentation":"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.","triggerScenarios":"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.","commonSituations":"Corrupted or incompatible gregex/GoFrame version after an upgrade; panic-level bug surfaced as error from the regex call.","solutions":["Upgrade/verify the GoFrame gregex dependency version","Replace the two regex calls with plain strings.Replace for these fixed strings, eliminating regex errors entirely","Reproduce with a small test calling gregex.ReplaceString with the same pattern"],"exampleFix":"// before\ncontent, err = gregex.ReplaceString(`\\n*#\\s+-o\\s+smtpd_tls_auth_only=yes`, \"\\n  -o smtpd_tls_auth_only=yes\", content)\nif err != nil {\n    return fmt.Errorf(\"failed to update postfix master config: %v\", err)\n}\n// after\ncontent = strings.ReplaceAll(content, \"#  -o smtpd_tls_auth_only=yes\", \"  -o smtpd_tls_auth_only=yes\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := certService.SetPostfixMasterSSL(); err != nil {\n    if strings.Contains(err.Error(), \"failed to update postfix master config\") {\n        log.Errorf(\"regex rewrite of master.cf failed: %s\", err)\n        return fmt.Errorf(\"could not enable smtpd_tls_auth_only; pin/upgrade gregex: %w\", err)\n    }\n    return err\n}","preventionTips":["Prefer strings.ReplaceAll over regex for fixed strings in master.cf","Pin and test the GoFrame version in CI","Add a unit test that runs the replacement against a sample master.cf"],"tags":["postfix","regex","configuration","go"],"backgroundTag":"regex-compile-failed","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}