caddyserver/caddy · error
acme_dns specified without DNS provider config, but no provi
Error message
acme_dns specified without DNS provider config, but no provider specified with 'dns' global option
What it means
fillInGlobalACMEDefaults applies global 'acme_dns' to ACME issuers. parseOptDNS allows writing 'acme_dns' with NO arguments — it parses to nil, meaning 'inherit the globally-defined dns provider'. This error fires when that is the case (acme_dns key present, value nil) AND the issuer's DNS challenge has no provider AND options['dns'] is also nil: there is no provider anywhere to wire in, so the adapter errors instead of producing a providerless DNS challenge.
Source
Thrown at caddyconfig/httpcaddyfile/tlsapp.go:548
globalACMEEAB := options["acme_eab"]
globalPreferredChains := options["preferred_chains"]
globalCertLifetime := options["cert_lifetime"]
globalHTTPPort, globalHTTPSPort := options["http_port"], options["https_port"]
globalDefaultBind := options["default_bind"]
if globalEmail != nil && acmeIssuer.Email == "" {
acmeIssuer.Email = globalEmail.(string)
}
if globalACMECA != nil && acmeIssuer.CA == "" {
acmeIssuer.CA = globalACMECA.(string)
}
if globalACMECARoot != nil && !slices.Contains(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string)) {
acmeIssuer.TrustedRootsPEMFiles = append(acmeIssuer.TrustedRootsPEMFiles, globalACMECARoot.(string))
}
if globalACMEDNSok && (acmeIssuer.Challenges == nil || acmeIssuer.Challenges.DNS == nil || acmeIssuer.Challenges.DNS.ProviderRaw == nil) {
globalDNS := options["dns"]
if globalDNS == nil && globalACMEDNS == nil {
return fmt.Errorf("acme_dns specified without DNS provider config, but no provider specified with 'dns' global option")
}
if acmeIssuer.Challenges == nil {
acmeIssuer.Challenges = new(caddytls.ChallengesConfig)
}
if acmeIssuer.Challenges.DNS == nil {
acmeIssuer.Challenges.DNS = new(caddytls.DNSChallengeConfig)
}
if globalACMEDNS != nil && acmeIssuer.Challenges.DNS.ProviderRaw == nil {
// Set a global DNS provider if `acme_dns` is set
acmeIssuer.Challenges.DNS.ProviderRaw = caddyconfig.JSONModuleObject(globalACMEDNS, "name", globalACMEDNS.(caddy.Module).CaddyModule().ID.Name(), nil)
}
}
if globalACMEEAB != nil && acmeIssuer.ExternalAccount == nil {
acmeIssuer.ExternalAccount = globalACMEEAB.(*acme.EAB)
}
if globalPreferredChains != nil && acmeIssuer.PreferredChains == nil {
acmeIssuer.PreferredChains = globalPreferredChains.(*caddytls.ChainPreference)
}View on GitHub (pinned to 50e54ee279)
Solutions
- Give acme_dns its provider: 'acme_dns cloudflare {env.CF_API_TOKEN}'.
- Or keep bare 'acme_dns' and add the global 'dns cloudflare {env.CF_API_TOKEN}' option it inherits from.
- Remove 'acme_dns' entirely if no DNS challenge is wanted.
- Ensure the DNS provider plugin is in the build ('caddy list-modules | grep dns.providers').
Example fix
# before
{
acme_dns
}
# after
{
acme_dns cloudflare {env.CF_API_TOKEN}
}
# or
{
dns cloudflare {env.CF_API_TOKEN}
acme_dns
} Defensive patterns
Strategy: validation
Validate before calling
grep -nE '^\s*acme_dns\s*$' Caddyfile # bare acme_dns with no provider and no global 'dns' option will fail
Prevention
- Always give acme_dns a provider argument, or pair bare acme_dns with a global dns provider.
- Keep xcaddy build commands alongside the Caddyfile so DNS plugins are present.
When it happens
Trigger: A global block containing bare 'acme_dns' (no module name/args) while no global 'dns <provider> ...' option exists anywhere in the config.
Common situations: Copy-pasting an acme_dns line and losing its provider argument; intending to centralize the provider via 'dns' but forgetting that option; templates that emit 'acme_dns' unconditionally.
Related errors
- filling in global issuer defaults for AP %d, issuer %d: %v
- filling in global issuer defaults for issuer %d: %v
- global options are ambiguous: local_certs is confusing when
- expanding DNS override domain '%s': %v
- loading DNS provider module: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/8e99c5f31bc793d9.
Report an issue: GitHub.