Billionmail/BillionMail · error
Failed to set HTTP verification: {}
Error message
Failed to set HTTP verification: {} What it means
ApplySSLWithExistingServer configures a lego ACME client to solve the HTTP-01 challenge by registering a custom provider bound to 127.0.0.1:60880 via client.Challenge.SetHTTP01Provider. The error wraps any failure returned by lego when installing that provider. In lego this call essentially cannot fail for the built-in http01.ProviderServer, so hitting it indicates a programming bug, a nil client, or a forked/modified lego version whose SetHTTP01Provider performs extra validation.
Source
Thrown at core/internal/service/acme/acme.go:401
// Get configuration
config := GetConfig(myUser)
if config == nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to get configuration"))
}
client, err := lego.NewClient(config)
if err != nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to create ACME client: {}", err.Error()))
}
// Set verification method
if vtype == "http" {
// Assume the HTTP server is already running and properly configured
// to handle the challenge requests
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("127.0.0.1", "60880"))
if err != nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to set HTTP verification: {}", err.Error()))
}
} else if vtype == "dns" && dnsProvider != "" {
// Set DNS verification - same as in the standard ApplySSL function
switch dnsProvider {
case "tencentcloud":
err = SetDnsTencentcloud(ctx, client, dnsProviderToken)
if err != nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to set Tencent Cloud DNS verification: {}", err.Error()))
}
case "alidns":
err = SetDnsAliyun(ctx, client, dnsProviderToken)
if err != nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to set Alibaba Cloud DNS verification: {}", err.Error()))
}
case "cloudxns":
err = SetDnsCloudxns(ctx, client, dnsProviderToken)
if err != nil {
return "", "", errors.New(public.LangCtx(ctx, "Failed to set CloudXNS DNS verification: {}", err.Error()))View on GitHub (pinned to fc36c76c05)
Solutions
- Inspect the wrapped err.Error() in the message; if it is empty or nil-related, verify the lego ACME client is constructed with a valid user private key before ApplySSLWithExistingServer is called
- Pin lego to the version upstream BillionMail was built against (go.mod) so SetHTTP01Provider matches the expected no-error behavior
- If running custom challenge logic, ensure the HTTP server actually listens on 127.0.0.1:60880 before requesting the certificate, since the challenge will fail later otherwise
Example fix
// before
client, err := lego.NewClient(lego.NewConfig())
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("127.0.0.1", "60880"))
// after
client, err := lego.NewClient(lego.NewConfigForUser(myUser)) // valid key loaded
if err != nil { return "", "", err }
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("127.0.0.1", "60880")) Defensive patterns
Strategy: try-catch
Validate before calling
if client == nil || client.Challenge == nil {
return fmt.Errorf("ACME client not initialized before SetHTTP01Provider")
}
// also ensure the challenge port is free:
if ln, err := net.Listen("tcp", "127.0.0.1:60880"); err != nil {
return fmt.Errorf("port 60880 already in use: %w", err)
} else { ln.Close() } Type guard
func acmeClientReady(c *lego.Client) bool { return c != nil && c.Challenge != nil } Try / catch
cert, _, err := ApplySSLWithExistingServer(ctx, ...)
if err != nil {
if strings.Contains(err.Error(), "Failed to set HTTP verification") {
log.Printf("challenge provider setup failed: %v", err) // inspect lego cause
}
return err
} Prevention
- Always construct the lego client with a valid user key before setting providers
- Pin the lego dependency version in go.mod to avoid behavioral drift
- Confirm port 60880 is free and the HTTP server is up before requesting http-01 certificates
When it happens
Trigger: Calling ApplySSLWithExistingServer (via Apply, StartRenew, ApplyLetsEncryptCertWithHttp, or ApplyConsoleCert) with vtype == "http" while client.Challenge is nil/nil-initialized, or using a lego version where SetHTTP01Provider returns an error.
Common situations: Custom builds of lego with extra provider validation; a client constructed incorrectly (missing user key so Challenge chain misbehaves); copy-pasted code that nils out the Challenge map before this call.
Related errors
- DNS verification setup failed: {}
- Failed to get configuration
- Failed to create ACME client: {}
- Failed to apply for SSL certificate: {}
- fail to check domain: %w
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/7ca4b5194f1d8b95.
Report an issue: GitHub.