{"record":{"id":"7a82f3018bc23743","repo":"Billionmail/BillionMail","slug":"333333write-new-dovecot-sql-conf-ext-failed-w","errorCode":null,"errorMessage":"333333write new dovecot-sql.conf.ext failed: %w","messagePattern":"333333write new dovecot-sql\\.conf\\.ext failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/mail_boxes/init_quota_plugin.go","lineNumber":195,"sourceCode":"\t//}\n\n\tdbPass, _ := public.DockerEnv(\"DBPASS\")\n\tdbName, _ := public.DockerEnv(\"DBNAME\")\n\tdbUser, _ := public.DockerEnv(\"DBUSER\")\n\n\tcontent := fmt.Sprintf(`driver = pgsql\nconnect = host=pgsql dbname=%s user=%s password=%s\n\ndefault_pass_scheme = MD5-CRYPT\n\nuser_query = SELECT '/var/vmail/%%d/%%n' as home, 'maildir:/var/vmail/%%d/%%n' as mail, 150 AS uid, 8 AS gid, 'maildir:storage=' || quota AS quota FROM mailbox WHERE username = '%%u' AND active = 1\n\npassword_query = SELECT username as user, password, '/var/vmail/%%d/%%n' as userdb_home, 'maildir:/var/vmail/%%d/%%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = '%%u' AND active = 1\n`, dbName, dbUser, dbPass)\n\n\terr := ioutil.WriteFile(path, []byte(content), 0644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"333333write new dovecot-sql.conf.ext failed: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc AddMaildirsizeFileForAllMailboxes(ctx context.Context) error {\n\n\tif _, err := g.DB().Exec(ctx, \"ALTER TABLE mailbox ADD COLUMN IF NOT EXISTS quota_active SMALLINT NOT NULL DEFAULT 1\"); err != nil {\n\t\tg.Log().Warning(ctx, \"ensure quota_active column failed\", err)\n\t}\n\n\ttype Row struct {\n\t\tUsername    string\n\t\tLocalPart   string\n\t\tDomain      string\n\t\tQuota       int64\n\t\tQuotaActive int\n\t}","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/mail_boxes/init_quota_plugin.go#L177-L213","documentation":"recreateSqlConf regenerates dovecot-sql.conf.ext with DB credentials and writes it with ioutil.WriteFile. This error (with an accidental '333333' debug prefix left in the message) wraps any write failure, so the new SQL auth config could not be saved.","triggerScenarios":"ioutil.WriteFile(path, content, 0644) fails: directory missing, permission denied, read-only filesystem, or disk full while writing dovecot-sql.conf.ext.","commonSituations":"dovecot conf dir mounted read-only in the container; process user lacks write access; disk quota exceeded on the volume; leftover debug prefix '333333' indicates an unfinished debugging session in the code.","solutions":["Check permissions/ownership of the dovecot conf directory and file","Verify the volume is writable and has free space (df -h)","Ensure the directory exists before writing (os.MkdirAll on filepath.Dir(path))","Remove the stray '333333' debug prefix from the error message"],"exampleFix":"// before\nreturn fmt.Errorf(\"333333write new dovecot-sql.conf.ext failed: %w\", err)\n// after\nreturn fmt.Errorf(\"write new dovecot-sql.conf.ext at %s failed: %w\", path, err)","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(path)\nif err := os.MkdirAll(dir, 0755); err != nil {\n\treturn fmt.Errorf(\"cannot create %s: %v\", dir, err)\n}\nif f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644); err != nil {\n\treturn fmt.Errorf(\"dovecot-sql.conf.ext not writable: %v\", err)\n} else {\n\tf.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := mail_boxes.InitQuotaPluginAndUpdateUsedSpace(ctx); err != nil && strings.Contains(err.Error(), \"write new dovecot-sql.conf.ext failed\") {\n\tlog.Printf(\"check dovecot conf volume writability/disk space: %v\", errors.Unwrap(err))\n}","preventionTips":["Mount the dovecot conf volume read-write","Monitor disk space on the config volume","Ensure the process user owns the conf directory","Remove debug-prefix artifacts from error messages"],"tags":["filesystem","dovecot","write-failure","sql-config"],"backgroundTag":"file-write-permission-denied","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"}