Billionmail/BillionMail · error
certificate content is empty in database
Error message
certificate content is empty in database
What it means
After a certificate row is found, getSSLInfoFromDatabase checks cert.Certificate is non-empty. An empty PEM blob means the row exists but the certificate content column was never populated or was cleared, so there is nothing to parse or serve.
Source
Thrown at core/internal/service/mail_service/certificate.go:513
NotAfter string `json:"not_after"`
NotBefore string `json:"not_before"`
Dns string `json:"dns"`
}
err = g.DB().Model("letsencrypts").
Where("dns::jsonb ? $1", public.FormatMX(domain)).
Where("status = 1").
Where("endtime > ?", time.Now().Unix()).
Order("endtime desc").
Limit(1).
Scan(&cert)
if err != nil {
return certInfo, fmt.Errorf("certificate not found in database: %v", err)
}
if cert.Certificate == "" {
return certInfo, fmt.Errorf("certificate content is empty in database")
}
// Parse certificate information
err = gconv.Struct(acme.GetCertInfo(cert.Certificate), &certInfo)
if err != nil {
return certInfo, fmt.Errorf("failed to parse certificate info: %v", err)
}
// Set certificate content
certInfo.CertPem = cert.Certificate
certInfo.KeyPem = cert.PrivateKey
return certInfo, nil
}
// getSSLInfoFromFiles retrieves SSL certificate from file system (legacy method)
func (c *Certificate) getSSLInfoFromFiles(domain string) (certInfo v1.CertInfo, err error) {
csrPath := filepath.Join(consts.SSL_PATH, domain, "/fullchain.pem")View on GitHub (pinned to fc36c76c05)
Solutions
- Re-issue or re-upload the certificate so the certificate column contains valid PEM.
- Delete the empty row so the service falls back to a valid certificate or triggers issuance.
- Check the issuance pipeline for steps that persist the row before the PEM is available.
- Inspect the row directly (SELECT certificate FROM ... ) to confirm emptiness.
Defensive patterns
Strategy: validation
Validate before calling
var pem string
err := g.DB().Model("certificates").Where("endtime > ?", time.Now().Unix()).Order("endtime desc").Limit(1).Value("certificate").Scan(&pem)
if err != nil || !strings.Contains(pem, "BEGIN CERTIFICATE") {
// row empty or invalid — re-issue before calling GetSSLInfo
} Try / catch
if err := GetSSLStatus(ctx); err != nil {
if strings.Contains(err.Error(), "certificate content is empty") {
return reissueCertificate(ctx)
}
return err
} Prevention
- Never insert certificate rows manually with placeholder content.
- Make issuance transactions atomic: write PEM in the same transaction as the row.
- Add a health check that flags cert rows with empty content.
When it happens
Trigger: GetSSLInfo reads a DB row where the certificate column is '' — e.g. a record created by a failed issuance, manual row insertion, or a wiped/placeholder row.
Common situations: Issuance job crashed after inserting the row but before writing PEM content; admin deleted cert content while debugging; backup/restore truncated large text columns.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- certificate not found in database: %v
- fail to check domain: %w
- fail to set ssl: %w
- Failed to create directory: {}
- Failed to save certificate file: {}
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/64351fb3e90c6220.
Report an issue: GitHub.