{"record":{"id":"3ab9946a8af03010","repo":"Billionmail/BillionMail","slug":"domain-s-does-not-exist","errorCode":null,"errorMessage":"domain %s does not exist","messagePattern":"domain (.+?) does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/controller/domains/domains_v1_set_ssl.go","lineNumber":23,"sourceCode":"\t\"billionmail-core/internal/service/domains\"\n\t\"billionmail-core/internal/service/mail_service\"\n\t\"billionmail-core/internal/service/public\"\n\t\"context\"\n\t\"fmt\"\n\n\t\"billionmail-core/api/domains/v1\"\n)\n\nfunc (c *ControllerV1) SetSSL(ctx context.Context, req *v1.SetSSLReq) (res *v1.SetSSLRes, err error) {\n\tres = &v1.SetSSLRes{}\n\n\tif ex, err1 := domains.Exists(ctx, req.Domain); !ex {\n\t\tif err1 != nil {\n\t\t\tres.SetError(fmt.Errorf(\"fail to check domain: %w\", err1))\n\t\t\treturn\n\t\t}\n\n\t\tres.SetError(fmt.Errorf(\"domain %s does not exist\", req.Domain))\n\t\treturn\n\t}\n\n\tcrt := mail_service.NewCertificate()\n\n\tdefer crt.Close()\n\n\terr = crt.SetSNI(public.FormatMX(req.Domain), req.Certificate, req.Key)\n\n\tif err != nil {\n\t\tres.SetError(fmt.Errorf(\"fail to set ssl: %w\", err))\n\t\treturn\n\t}\n\n\t_ = public.WriteLog(ctx, public.LogParams{\n\t\tType: consts.LOGTYPE.Domain,\n\t\tLog:  \"Set SSL for domain :\" + req.Domain + \" successfully\",\n\t\tData: req,","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/controller/domains/domains_v1_set_ssl.go#L5-L41","documentation":"SetSSL refuses to configure SSL for a domain that is not registered in the system. Before creating the SNI certificate, the controller calls domains.Exists(ctx, req.Domain) to confirm the domain row is present; if not, it aborts with this error. It prevents setting SSL certificates for arbitrary or mistyped domains that the mail stack does not manage.","triggerScenarios":"Calling the SetSSL API with req.Domain spelled differently from the stored domain (e.g. missing subdomain, trailing dot, uppercase), or calling it after the domain was deleted, or before the domain was added via the domains API.","commonSituations":"Typos in the domain name; using the bare zone apex when a subdomain is registered (or vice versa); a race where another admin removed the domain; operating against a fresh install where domains have not been imported yet.","solutions":["Add the domain first via the domains create API, then retry SetSSL.","Verify the exact stored domain string (list domains) and correct req.Domain, including case and trailing characters.","If 'fail to check domain' accompanies it, resolve the underlying DB error surfaced by that wrapper first."],"exampleFix":"// before\ncurl -X POST /api/v1/domains/ssl -d '{\"domain\":\"exmaple.com\", ...}'\n// after\ncurl -X POST /api/v1/domains/ssl -d '{\"domain\":\"example.com\", ...}'  // domain added beforehand","handlingStrategy":"validation","validationCode":"// Go: confirm the domain exists before calling SetSSL\nexists, err := domainsClient.Exists(ctx, domain)\nif err != nil || !exists {\n    return fmt.Errorf(\"domain %s must be added before setting SSL\", domain)\n}","typeGuard":null,"tryCatchPattern":"if err := setSSL(domain, cert, key); err != nil {\n    if strings.Contains(err.Error(), \"does not exist\") {\n        // create the domain, then retry once\n    }\n    return err\n}","preventionTips":["Always create/list the domain before configuring SSL for it.","Normalize domain input (trim, lowercase, strip trailing dot) before sending.","Copy the domain string from the domains list API rather than retyping it."],"tags":["domains","ssl","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}