Billionmail/BillionMail · error

fail to set ssl: %w

Error message

fail to set ssl: %w

What it means

SetSSL wraps any error from crt.SetSNI(public.FormatMX(req.Domain), req.Certificate, req.Key) with this message. SetSNI installs the certificate/key pair as an SNI entry for the mail hostname (mail.example.com) in the mail server config, so failures mean the cert could not be written or applied.

Source

Thrown at core/internal/controller/domains/domains_v1_set_ssl.go:34

	if ex, err1 := domains.Exists(ctx, req.Domain); !ex {
		if err1 != nil {
			res.SetError(fmt.Errorf("fail to check domain: %w", err1))
			return
		}

		res.SetError(fmt.Errorf("domain %s does not exist", req.Domain))
		return
	}

	crt := mail_service.NewCertificate()

	defer crt.Close()

	err = crt.SetSNI(public.FormatMX(req.Domain), req.Certificate, req.Key)

	if err != nil {
		res.SetError(fmt.Errorf("fail to set ssl: %w", err))
		return
	}

	_ = public.WriteLog(ctx, public.LogParams{
		Type: consts.LOGTYPE.Domain,
		Log:  "Set SSL for domain :" + req.Domain + " successfully",
		Data: req,
	})

	res.SetSuccess(public.LangCtx(ctx, "Success"))
	return
}

View on GitHub (pinned to fc36c76c05)

Solutions

  1. Validate that req.Key is the private key corresponding to req.Certificate (compare modulus/pubkey) and both are valid PEM.
  2. Ensure the full chain (leaf + intermediates) is included and markers/line endings are intact.
  3. Inspect the wrapped inner error (%w) for the exact SetSNI failure and fix filesystem/permission issues it reports.
  4. Restart the mail service if config was partially written, then retry.

Example fix

// before
{"certificate":"-----BEGIN CERTIFICATE-----\nMIIB...", "key":"<ssh key by mistake>"}
// after
{"certificate":"-----BEGIN CERTIFICATE-----\n...CHAIN...\n-----END CERTIFICATE-----", "key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: match cert and key, and check PEM markers
certPub := extractPubKey(certPEM)
keyPub := extractPubKey(keyPEM)
if !bytes.Equal(certPub, keyPub) {
    return errors.New("certificate and private key do not match")
}
if !strings.Contains(certPEM, "BEGIN CERTIFICATE") || !strings.Contains(keyPEM, "BEGIN") {
    return errors.New("invalid PEM content")
}

Try / catch

if err := setSSL(domain, cert, key); err != nil {
    var inner error
    errors.As(err, &inner) // message is 'fail to set ssl: %w'; log the unwrapped cause
    return fmt.Errorf("SSL install failed: %v", inner)
}

Prevention

When it happens

Trigger: Passing an invalid PEM certificate or mismatched private key in req.Certificate/req.Key; empty cert/key fields; SetSNI failing to update the underlying mail service config; file permission problems writing the cert store.

Common situations: Uploading a cert whose key does not match; cert chain in wrong order; pasting a cert with Windows line endings or missing BEGIN/END markers; container lacking write access to the cert directory; Docker volume not mounted.

Understand the failure class

Related errors


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