Billionmail/BillionMail · error

Generate password md5-crypt failed: %w

Error message

Generate password md5-crypt failed: %w

What it means

Add (mailbox creation) hashes the plaintext password with md5-crypt via PasswdMD5Crypt for Dovecot compatibility. If the crypt operation fails, the error is wrapped as 'Generate password md5-crypt failed'.

Source

Thrown at core/internal/service/mail_boxes/mail_boxes.go:32

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"math/rand"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"
)

func Add(ctx context.Context, mailbox *v1.Mailbox) (err error) {
	// Encode password
	mailbox.PasswordEncode = PasswdEncode(ctx, mailbox.Password)

	// Crypt password
	mailbox.Password, err = PasswdMD5Crypt(ctx, mailbox.Password)

	if err != nil {
		err = fmt.Errorf("Generate password md5-crypt failed: %w", err)
		return
	}

	mailbox.Username = strings.ToLower(mailbox.Username)
	mailbox.LocalPart = strings.ToLower(mailbox.LocalPart)
	mailbox.Domain = strings.ToLower(mailbox.Domain)

	now := time.Now().Unix()
	mailbox.CreateTime = now
	mailbox.UpdateTime = now
	mailbox.Active = 1
	mailbox.Maildir = fmt.Sprintf("%s@%s/", mailbox.LocalPart, mailbox.Domain)

	_, err = g.DB().Model("mailbox").Ctx(ctx).Insert(mailbox)
	if err != nil {
		if strings.Contains(err.Error(), "duplicate") || strings.Contains(err.Error(), "unique") {
			return fmt.Errorf("mailbox %s already exists", mailbox.Username)
		}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Validate the password is non-empty and within length limits before calling Add
  2. Inspect the wrapped %w error for the underlying crypt failure
  3. Regenerate with a supported md5-crypt implementation / update the crypt library
  4. Confirm crypto/rand entropy sources are available in the container

Example fix

// before
mailbox.Password, err = PasswdMD5Crypt(ctx, mailbox.Password)
// after
if mailbox.Password == "" {
	return fmt.Errorf("mailbox password must not be empty")
}
mailbox.Password, err = PasswdMD5Crypt(ctx, mailbox.Password)
if err != nil {
	err = fmt.Errorf("Generate password md5-crypt failed: %w", err)
	return
}
Defensive patterns

Strategy: validation

Validate before calling

func validPassword(pw string) bool {
	return len(pw) >= 8 && len(pw) <= 128
}
if !validPassword(mailbox.Password) {
	return fmt.Errorf("password length must be 8-128 characters")
}

Try / catch

err := mail_boxes.Add(ctx, mailbox)
if err != nil && strings.Contains(err.Error(), "Generate password md5-crypt failed") {
	log.Printf("reject input: %v", errors.Unwrap(err))
}

Prevention

When it happens

Trigger: PasswdMD5Crypt(ctx, mailbox.Password) returns an error — typically an empty/oversized password, or a failure in the underlying crypt library (unsupported algorithm, salt generation failure, crypto/rand unavailable).

Common situations: API caller submits a mailbox with an empty password field; password containing characters truncated by an upstream validator; environment where /dev/urandom is unavailable; upgrading a crypt dependency with changed behavior.

Related errors


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