Billionmail/BillionMail · error

333333write new dovecot-sql.conf.ext failed: %w

Error message

333333write new dovecot-sql.conf.ext failed: %w

What it means

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.

Source

Thrown at core/internal/service/mail_boxes/init_quota_plugin.go:195

	//}

	dbPass, _ := public.DockerEnv("DBPASS")
	dbName, _ := public.DockerEnv("DBNAME")
	dbUser, _ := public.DockerEnv("DBUSER")

	content := fmt.Sprintf(`driver = pgsql
connect = host=pgsql dbname=%s user=%s password=%s

default_pass_scheme = MD5-CRYPT

user_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

password_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
`, dbName, dbUser, dbPass)

	err := ioutil.WriteFile(path, []byte(content), 0644)
	if err != nil {
		return fmt.Errorf("333333write new dovecot-sql.conf.ext failed: %w", err)
	}

	return nil
}

func AddMaildirsizeFileForAllMailboxes(ctx context.Context) error {

	if _, err := g.DB().Exec(ctx, "ALTER TABLE mailbox ADD COLUMN IF NOT EXISTS quota_active SMALLINT NOT NULL DEFAULT 1"); err != nil {
		g.Log().Warning(ctx, "ensure quota_active column failed", err)
	}

	type Row struct {
		Username    string
		LocalPart   string
		Domain      string
		Quota       int64
		QuotaActive int
	}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Check permissions/ownership of the dovecot conf directory and file
  2. Verify the volume is writable and has free space (df -h)
  3. Ensure the directory exists before writing (os.MkdirAll on filepath.Dir(path))
  4. Remove the stray '333333' debug prefix from the error message

Example fix

// before
return fmt.Errorf("333333write new dovecot-sql.conf.ext failed: %w", err)
// after
return fmt.Errorf("write new dovecot-sql.conf.ext at %s failed: %w", path, err)
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
	return fmt.Errorf("cannot create %s: %v", dir, err)
}
if f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
	return fmt.Errorf("dovecot-sql.conf.ext not writable: %v", err)
} else {
	f.Close()
}

Try / catch

if err := mail_boxes.InitQuotaPluginAndUpdateUsedSpace(ctx); err != nil && strings.Contains(err.Error(), "write new dovecot-sql.conf.ext failed") {
	log.Printf("check dovecot conf volume writability/disk space: %v", errors.Unwrap(err))
}

Prevention

When it happens

Trigger: ioutil.WriteFile(path, content, 0644) fails: directory missing, permission denied, read-only filesystem, or disk full while writing dovecot-sql.conf.ext.

Common situations: 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.

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


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