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

  1. Provide both keyConfig["APIKey"] (Cloudflare Global API Key) and keyConfig["Email"] (account email).
  2. If using an API Token instead, switch to the token-based config fields rather than Email+APIKey.
  3. Verify the map keys are exactly 'APIKey' and 'Email'.
  4. 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

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


AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05). Data as JSON: /api/errors/e819e78089cdbbd8. Report an issue: GitHub.