Billionmail/BillionMail · error
DNS automated resolution failed: APIKey or Email is empty in
Error message
DNS automated resolution failed: APIKey or Email is empty in Cloudflare configuration file
What it means
SetDnsCloudflare configures the lego Cloudflare DNS-01 provider using the legacy global API key auth scheme (AuthEmail + AuthKey). It validates that keyConfig has non-empty 'APIKey' and 'Email'; otherwise it returns this error. Cloudflare's global API key authentication requires both the key and the account email.
Source
Thrown at core/internal/service/acme/acme.go:186
}
err = client.Challenge.SetDNS01Provider(p)
if err != nil {
return errors.New(public.LangCtx(ctx, "DNS verification setup failed: {}", err.Error()))
}
return nil
}
/**
* @description: Configure DNS verification via Cloudflare
* @param {*lego.Client} client Client
* @param {map[string]string} keyConfig Configuration information
* @return error Error information
*/
func SetDnsCloudflare(ctx context.Context, client *lego.Client, keyConfig map[string]string) error {
if keyConfig == nil || keyConfig["APIKey"] == "" || keyConfig["Email"] == "" {
return errors.New(public.LangCtx(ctx, "DNS automated resolution failed: APIKey or Email is empty in Cloudflare configuration file"))
}
cfg := cloudflare.NewDefaultConfig()
cfg.AuthEmail = keyConfig["Email"]
cfg.AuthKey = keyConfig["APIKey"]
p, err := cloudflare.NewDNSProviderConfig(cfg)
if err != nil {
return errors.New(public.LangCtx(ctx, "DNS provider initialization failed: {}", err.Error()))
}
err = client.Challenge.SetDNS01Provider(p)
if err != nil {
return errors.New(public.LangCtx(ctx, "DNS verification setup failed: {}", err.Error()))
}
return nil
}View on GitHub (pinned to fc36c76c05)
Solutions
- Provide both keyConfig["APIKey"] (Cloudflare Global API Key) and keyConfig["Email"] (account email).
- If using an API Token instead, switch to the token-based config fields rather than Email+APIKey.
- Verify the map keys are exactly 'APIKey' and 'Email'.
- Re-generate/copy the Global API Key from Cloudflare dashboard (My Profile -> API Tokens).
Example fix
// before
keyConfig := map[string]string{"APIKey": cfKey} // email missing
// after
keyConfig := map[string]string{"APIKey": cfKey, "Email": "user@example.com"} Defensive patterns
Strategy: validation
Validate before calling
if ak, em := keyConfig["APIKey"], keyConfig["Email"]; ak == "" || em == "" {
return errors.New("cloudflare DNS config requires non-empty APIKey (Global API Key) and Email")
} Type guard
func hasCloudflareGlobalKey(m map[string]string) bool {
return m != nil && m["APIKey"] != "" && m["Email"] != ""
} Prevention
- Clarify in the UI that Global API Key + Email is required, not an API Token.
- Validate both fields non-empty before saving the provider config.
- Use exact map keys APIKey and Email.
- Re-copy the Global API Key after any rotation in Cloudflare.
When it happens
Trigger: Calling ApplySSLWithExistingServer with dnsProvider 'cloudflare' whose keyConfig is nil or has empty 'APIKey'/'Email' entries (acme.go:185-187).
Common situations: User supplied a Cloudflare API Token instead of the global API key (token flow needs AuthToken, not Email+AuthKey); email field left blank in the panel; keys renamed in the config map ('authEmail'); global API key disabled/rotated in the Cloudflare dashboard.
Related errors
- DNS automated resolution failed: SecretId or SecretKey is em
- DNS automated resolution failed: APIKey or SecretKey is empt
- DNS automated resolution failed: APIKey or SecretKey is empt
- DNS provider initialization failed: {}
- DNS automated resolution failed: ClientID, ClientSecret or T
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/e819e78089cdbbd8.
Report an issue: GitHub.