caddyserver/caddy · error
filling in global issuer defaults for AP %d, issuer %d: %v
Error message
filling in global issuer defaults for AP %d, issuer %d: %v
What it means
During TLS app finalization, each automation policy's issuers get global ACME defaults filled in (fillInGlobalACMEDefaults: email, acme_ca, acme_ca_root, acme_dns, acme_eab, preferred_chains, ...). Inspecting fillInGlobalACMEDefaults shows its only failing path is the acme_dns-without-provider check, so this wrapper ('for AP %d, issuer %d') almost always wraps exactly that error, with the policy and issuer indexes telling you which entry triggered it.
Source
Thrown at caddyconfig/httpcaddyfile/tlsapp.go:473
ap.Issuers = caddytls.DefaultIssuers(emailStr)
// if a specific endpoint is configured, can't use multiple default issuers
if globalACMECA != nil {
ap.Issuers = []certmagic.Issuer{new(caddytls.ACMEIssuer)}
}
}
}
}
}
// finalize and verify policies; do cleanup
if tlsApp.Automation != nil {
for i, ap := range tlsApp.Automation.Policies {
// ensure all issuers have global defaults filled in
for j, issuer := range ap.Issuers {
err := fillInGlobalACMEDefaults(issuer, options)
if err != nil {
return nil, warnings, fmt.Errorf("filling in global issuer defaults for AP %d, issuer %d: %v", i, j, err)
}
}
// encode all issuer values we created, so they will be rendered in the output
if len(ap.Issuers) > 0 && ap.IssuersRaw == nil {
for _, iss := range ap.Issuers {
issuerName := iss.(caddy.Module).CaddyModule().ID.Name()
ap.IssuersRaw = append(ap.IssuersRaw, caddyconfig.JSONModuleObject(iss, "module", issuerName, &warnings))
}
}
}
// consolidate automation policies that are the exact same
tlsApp.Automation.Policies = consolidateAutomationPolicies(tlsApp.Automation.Policies)
// ensure automation policies don't overlap subjects (this should be
// an error at provision-time as well, but catch it in the adapt phase
// for convenience)View on GitHub (pinned to 50e54ee279)
Solutions
- Read the trailing '%v' of the message — it carries the underlying fillInGlobalACMEDefaults error (in practice: the acme_dns/DNS-provider error).
- Give 'acme_dns' a provider (e.g. 'acme_dns cloudflare {env.CF_API_TOKEN}') or add a global 'dns' provider so bare acme_dns can inherit it.
- Scope DNS challenge config to the specific site's tls block instead of globally.
- Run 'caddy adapt' / 'caddy validate' to iterate quickly.
Example fix
# before
{
acme_dns
}
# after
{
acme_dns cloudflare {env.CF_API_TOKEN}
} Defensive patterns
Strategy: validation
Validate before calling
caddy validate --config Caddyfile --adapter caddyfile # surfaces the wrapped fillInGlobalACMEDefaults error
Prevention
- Keep global acme_* options minimal and consistent with the issuers in use.
- Read the wrapped error after the colon to find the true cause.
When it happens
Trigger: An ACME-capable issuer in policy i whose DNS challenge has no provider while global 'acme_dns' was specified bare (nil) and no global 'dns' option exists; the indexes identify which policy/issuer combination hit it.
Common situations: Setting bare 'acme_dns' globally while per-site tls blocks create their own ACME issuers; migrating from per-site dns challenge config to global options incompletely.
Related errors
- acme_dns specified without DNS provider config, but no provi
- 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/53b7f9e70514e057.
Report an issue: GitHub.