{"record":{"id":"200b07e1c96a2332","repo":"Billionmail/BillionMail","slug":"failed-to-create-acme-client","errorCode":null,"errorMessage":"Failed to create ACME client: {}","messagePattern":"Failed to create ACME client: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/acme/acme.go","lineNumber":392,"sourceCode":"\tlogFile := GetLogFile(ctx)\n\tSetLog(logFile)\n\tdefer CloseLog(logFile)\n\n\t// Get user information\n\tmyUser, err := GetMyUser(ctx, email)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\n\t// Get configuration\n\tconfig := GetConfig(myUser)\n\tif config == nil {\n\t\treturn \"\", \"\", errors.New(public.LangCtx(ctx, \"Failed to get configuration\"))\n\t}\n\n\tclient, err := lego.NewClient(config)\n\tif err != nil {\n\t\treturn \"\", \"\", errors.New(public.LangCtx(ctx, \"Failed to create ACME client: {}\", err.Error()))\n\t}\n\n\t// Set verification method\n\tif vtype == \"http\" {\n\t\t// Assume the HTTP server is already running and properly configured\n\t\t// to handle the challenge requests\n\t\terr = client.Challenge.SetHTTP01Provider(http01.NewProviderServer(\"127.0.0.1\", \"60880\"))\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", errors.New(public.LangCtx(ctx, \"Failed to set HTTP verification: {}\", err.Error()))\n\t\t}\n\t} else if vtype == \"dns\" && dnsProvider != \"\" {\n\t\t// Set DNS verification - same as in the standard ApplySSL function\n\t\tswitch dnsProvider {\n\t\tcase \"tencentcloud\":\n\t\t\terr = SetDnsTencentcloud(ctx, client, dnsProviderToken)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", \"\", errors.New(public.LangCtx(ctx, \"Failed to set Tencent Cloud DNS verification: {}\", err.Error()))\n\t\t\t}","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/acme/acme.go#L374-L410","documentation":"lego.NewClient(config) failed while constructing the ACME client from the previously obtained *lego.Config. lego errors here when the config's private key is invalid or the user registration data is unusable — it cannot assemble a client without a workable key. The code wraps the library error with a localized message.","triggerScenarios":"Any ApplySSLWithExistingServer caller where the MyUser's private key is nil, corrupt, or of an unsupported type, so lego.NewClient rejects it during client construction.","commonSituations":"A persisted ACME account key file that was truncated/corrupted by disk issues; keys generated with unsupported algorithms or wrong PEM encoding; a user record deserialized from storage missing the key field; refactors that changed how the key is stored/loaded.","solutions":["Read the wrapped err.Error() — lego states whether the key is nil, malformed, or unsupported.","Regenerate the ACME account key (ECDSA P-256 or RSA 2048+) and re-register the account.","Verify the stored key file/record loads and parses (pem.Decode / x509.ParseECPrivateKey) before calling ApplySSLWithExistingServer.","Restore the account key from backup if it was corrupted in storage."],"exampleFix":"// before\nmyUser.key = loadRawKeyBytes() // raw bytes, not parsed\nclient, err := lego.NewClient(config)\n// after\nkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\nif err != nil {\n    return \"\", \"\", err\n}\nmyUser.key = key\nclient, err := lego.NewClient(config)","handlingStrategy":"try-catch","validationCode":"func accountKeyValid(key crypto.PrivateKey) error {\n    switch k := key.(type) {\n    case *ecdsa.PrivateKey:\n        return k.Validate()\n    case *rsa.PrivateKey:\n        return k.Validate()\n    default:\n        return fmt.Errorf(\"unsupported account key type %T\", key)\n    }\n}","typeGuard":"func usableAccountKey(u *MyUser) bool {\n    switch u.GetPrivateKey().(type) {\n    case *ecdsa.PrivateKey, *rsa.PrivateKey:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"client, err := lego.NewClient(config)\nif err != nil {\n    log.Printf(\"lego.NewClient failed: %v — regenerating account key\", err)\n    if regErr := reRegisterAcmeAccount(ctx, email); regErr != nil {\n        return \"\", \"\", regErr\n    }\n    return \"\", \"\", errors.New(\"ACME client rebuilt with new account key; retry\")\n}","preventionTips":["Persist the ACME account key with correct file permissions and verify it parses on load.","Generate keys with ecdsa P-256 (lego's default) — avoid exotic algorithms.","On NewClient failure, regenerate the key and re-register instead of failing permanently.","Back up the ACME account record so a corrupted key can be restored."],"tags":["go","acme","lego","private-key","client-init"],"backgroundTag":"acme-client-init-failed","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"}