Billionmail/BillionMail · error
invalid certificate
Error message
invalid certificate
What it means
SaveToDatabase parses the issued certificate with GetCertInfo and rejects it when the Subject field comes back empty, meaning the certificate PEM could not be parsed or is empty. This guards against persisting a malformed/blank certificate record. It indicates the certificate string passed in is not a valid PEM certificate.
Source
Thrown at core/internal/service/acme/cli.go:227
if err != nil {
return "", "", fmt.Errorf("failed to save private key: %v", err)
}
fmt.Printf("Certificate saved to: %s\n", certificatePath)
fmt.Printf("Private key saved to: %s\n", privateKeyPath)
return certificatePath, privateKeyPath, nil
}
/**
* @brief Save certificate to database
* @return error
*/
func (cli *AcmeCLI) SaveToDatabase(accountId int, certificate, privateKey string) (int, error) {
// Get certificate info
certInfo := GetCertInfo(certificate)
if certInfo.Subject == "" {
return 0, fmt.Errorf("invalid certificate")
}
// Prepare DNS names
dnsNames, _ := json.Marshal(cli.Domains)
// Prepare data
data := map[string]interface{}{
"account_id": accountId,
"certificate": certificate,
"private_key": privateKey,
"subject": certInfo.Subject,
"dns": string(dnsNames),
"not_before": certInfo.NotBefore,
"not_after": certInfo.NotAfter,
"endtime": certInfo.Endtime,
"issuer": certInfo.Issuer,
"auth_type": cli.VerifyType,
"dns_provider": cli.DnsProvider,View on GitHub (pinned to fc36c76c05)
Solutions
- Verify the certificate argument contains actual PEM content (-----BEGIN CERTIFICATE-----) not a file path
- Check GetCertInfo against the same certificate to see why Subject is empty
- Re-run Apply and confirm the certificate file is non-empty before saving
- Validate the certificate with openssl x509 -in cert.pem -noout -subject
Example fix
// before
err := cli.SaveToDatabase(accountId, certPath, keyPath)
// after
certPEM, _ := os.ReadFile(certPath)
if len(certPEM) == 0 { return errors.New("certificate file is empty") }
err := cli.SaveToDatabase(accountId, string(certPEM), keyPEM) Defensive patterns
Strategy: validation
Validate before calling
certPEM, err := os.ReadFile(certPath)
if err != nil || !bytes.Contains(certPEM, []byte("-----BEGIN CERTIFICATE-----")) {
return errors.New("certificate PEM missing or malformed")
}
if acme.GetCertInfo(string(certPEM)).Subject == "" {
return errors.New("certificate not parseable — refusing to save")
} Prevention
- Always pass PEM content, never a file path, to SaveToDatabase
- Validate with openssl x509 before persisting
- Confirm Apply returned non-empty paths and files are non-empty first
When it happens
Trigger: Calling SaveToDatabase with an empty certificate string, a certificate path instead of PEM content, or PEM that GetCertInfo cannot parse (truncated file, wrong file passed, previous Apply step partially failed).
Common situations: Passing a file path where PEM content is expected; the certificate file was saved empty due to an earlier write error; certificate chain file corrupted during transfer; calling SaveToDatabase before a successful Apply.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Unsupported DNS provider: {}
- email is required
- at least one domain is required
- verification type must be either 'http' or 'dns'
- DNS provider is required for DNS verification
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/d12bc01389e6e6e0.
Report an issue: GitHub.