{"record":{"id":"ac5d433383789981","repo":"Billionmail/BillionMail","slug":"let-s-encrypt-certificate-is-empty","errorCode":null,"errorMessage":"let's encrypt certificate is empty","messagePattern":"let's encrypt certificate is empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/acme/renew.go","lineNumber":83,"sourceCode":"\t})\n\n\t// Try to apply for certificate\n\tctx := gctx.New()\n\tcertificate, privateKey, err := ApplySSLWithExistingServer(ctx, domains, email, vtype, dnsProvider, dnsProviderToken, certPath)\n\tprogress := GetAcmeLogBody(ctx)\n\tif err != nil {\n\t\t// Update renewal log\n\t\tpublic.M(\"renew_logs\").Where(\"renew_id = ?\", renewId).Update(g.Map{\"status\": 2, \"progress\": progress, \"error_info\": err.Error()})\n\t\tg.Log().Error(context.Background(), \"Renew certificate failed: \", err.Error())\n\t\treturn err\n\t}\n\n\t// Certificate is empty\n\tif certificate == \"\" || privateKey == \"\" {\n\t\t// Update renewal log\n\t\tpublic.M(\"renew_logs\").Where(\"renew_id = ?\", renewId).Update(g.Map{\"status\": 2, \"progress\": progress, \"error_info\": \"let's encrypt certificate is empty\"})\n\t\tg.Log().Error(context.Background(), \"Renew certificate failed: let's encrypt certificate is empty\")\n\t\treturn errors.New(\"let's encrypt certificate is empty\")\n\t}\n\n\t// Update renewal log\n\tpublic.M(\"renew_logs\").Where(\"renew_id = ?\", renewId).Update(g.Map{\"status\": 1, \"progress\": progress, \"error_info\": \"\"})\n\tg.Log().Info(context.Background(), \"Renew certificate success for domains: \", domains)\n\n\tdnsNames := \"[]\"\n\tstatus := 1\n\tcertInfo := GetCertInfo(certificate)\n\tnotAfter := certInfo.NotAfter\n\tnotBefore := certInfo.NotBefore\n\tsubject := certInfo.Subject\n\tendTime := certInfo.Endtime\n\tdnsNamesBytes, err := json.Marshal(domains)\n\tif err == nil {\n\t\tdnsNames = string(dnsNamesBytes)\n\t}\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/acme/renew.go#L65-L101","documentation":"StartRenew aborts a certificate renewal when either the stored certificate or private key is empty, marking the renew_log with status 2 and this error_info, logging it, and returning the error. Renewal cannot proceed without both artifacts, so the routine fails fast before contacting Let's Encrypt-adjacent renewal logic.","triggerScenarios":"Calling StartRenew (via renewCommand or Renew) for a record whose certificate or privateKey column/string is empty — e.g., issuance never completed, a previous Apply/SaveToDatabase failure left blank values, or the DB row was created without cert data.","commonSituations":"Renewal scheduled for a domain whose initial issuance failed; certificate record wiped by a failed migration or manual DB edit; code path saved the DNS/record info but not the certificate after an ACME error.","solutions":["Verify the source certificate/private key in the database for this renew record — reissue via Apply if empty","Fix the upstream issuance failure so certificates are stored before renewal is scheduled","Check renew_logs.error_info for the history of why the cert is empty","Delete/repair the broken renew record and create a fresh one"],"exampleFix":"// before\nerr := acme.StartRenew(renewId)\n// after\ncert, key := loadCertAndKey(renewId)\nif cert == \"\" || key == \"\" {\n    return errors.New(\"re-run issuance for this domain before renewing\")\n}\nerr := acme.StartRenew(renewId)","handlingStrategy":"validation","validationCode":"cert, key := store.GetCertificateAndKey(renewId)\nif cert == \"\" || key == \"\" {\n    return fmt.Errorf(\"renew record %d has empty cert/key; reissue first\", renewId)\n}","typeGuard":null,"tryCatchPattern":"if err := acme.StartRenew(renewId); err != nil {\n    if err.Error() == \"let's encrypt certificate is empty\" {\n        scheduleReissue(renewId) // full Apply instead of renew\n    }\n    return err\n}","preventionTips":["Only schedule renewals after confirmed successful issuance","Alert on renew_logs rows with status 2","Backfill cert/key data before enabling auto-renew for imported records"],"tags":["acme","certificate","renewal","empty-value"],"backgroundTag":"certificate-missing-for-renewal","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}