Billionmail/BillionMail · error

DNS automated resolution failed: APIKey or SecretKey is…

Error message

DNS automated resolution failed: APIKey or SecretKey is empty in AliDNS configuration file

What it means

SetDnsAliyun configures the lego Alibaba Cloud (alidns) DNS-01 provider. It first validates keyConfig: if the map is nil or 'APIKey' (AccessKey ID) / 'SecretKey' (AccessKey Secret) are empty, it fails fast with this message. Alibaba Cloud DNS API calls require both an AccessKey ID and matching secret for signature authentication.

Solutions

  1. Set both keyConfig["APIKey"] (AccessKey ID) and keyConfig["SecretKey"] (AccessKey Secret) to non-empty values.
  2. Confirm exact map key spellings: 'APIKey' and 'SecretKey'.
  3. Create an Aliyun RAM AccessKey pair with DNS (alidns) permissions if credentials are missing.
  4. Re-save the provider config in the UI/database and verify the row is populated.

Example fix

// before
keyConfig := map[string]string{"AccessKeyId": ak} // wrong keys
// after
keyConfig := map[string]string{"APIKey": ak, "SecretKey": sk}
Defensive patterns

Strategy: validation

Validate before calling

if ak, sk := keyConfig["APIKey"], keyConfig["SecretKey"]; ak == "" || sk == "" {
    return errors.New("alidns DNS config requires non-empty APIKey and SecretKey")
}

Type guard

func hasAliyunKeys(m map[string]string) bool {
    return m != nil && m["APIKey"] != "" && m["SecretKey"] != ""
}

Prevention

When it happens

Trigger: Calling ApplySSLWithExistingServer with dnsProvider 'alidns' whose keyConfig is nil or has empty 'APIKey'/'SecretKey' entries (acme.go:157-159).

Common situations: Aliyun AccessKey created but only the ID stored; RAM user without enabled programmatic access keys; map keys renamed (e.g. 'AccessKeyId') so lookups return empty strings; DNS config never saved for the domain.

Related errors


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

Appendix: source

Thrown at core/internal/service/acme/acme.go:158

		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
}

/**
 * @description: Configure DNS verification via Alibaba Cloud
 * @param {*lego.Client} client Client
 * @param {map[string]string} keyConfig Configuration information
 * @return error Error information
 */
func SetDnsAliyun(ctx context.Context, client *lego.Client, keyConfig map[string]string) error {
	if keyConfig == nil || keyConfig["APIKey"] == "" || keyConfig["SecretKey"] == "" {
		return errors.New(public.LangCtx(ctx, "DNS automated resolution failed: APIKey or SecretKey is empty in AliDNS configuration file"))
	}

	cfg := alidns.NewDefaultConfig()
	cfg.APIKey = keyConfig["APIKey"]
	cfg.SecretKey = keyConfig["SecretKey"]

	p, err := alidns.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)