caddyserver/caddy · error
loading TLS automation management module: %s
Error message
loading TLS automation management module: %s
What it means
The automation policy explicitly lists certificate issuers (issuers, e.g. acme, internal, zerossl modules) and LoadModule failed for one of them. The wrapped error identifies which issuer and why — unknown module, invalid issuer options, or the issuer's own Provision failure.
Source
Thrown at modules/caddytls/automation.go:230
// store them on the policy before putting it on the config
// load and provision any cert manager modules
if ap.ManagersRaw != nil {
ap.hadExplicitManagers = true
vals, err := tlsApp.ctx.LoadModule(ap, "ManagersRaw")
if err != nil {
return fmt.Errorf("loading external certificate manager modules: %v", err)
}
for _, getCertVal := range vals.([]any) {
ap.Managers = append(ap.Managers, getCertVal.(certmagic.Manager))
}
}
// load and provision any explicitly-configured issuer modules
if ap.IssuersRaw != nil {
val, err := tlsApp.ctx.LoadModule(ap, "IssuersRaw")
if err != nil {
return fmt.Errorf("loading TLS automation management module: %s", err)
}
for _, issVal := range val.([]any) {
ap.Issuers = append(ap.Issuers, issVal.(certmagic.Issuer))
}
}
issuers := ap.Issuers
if len(issuers) == 0 && !ap.implicitTailscaleManagersOnly() {
var err error
issuers, err = DefaultIssuersProvisioned(tlsApp.ctx)
if err != nil {
return err
}
}
// build certmagic.Config and attach it to the policy
storage := ap.storage
if storage == nil {View on GitHub (pinned to 50e54ee279)
Solutions
- Read the wrapped error (%s) — it names the failing issuer and cause; correct the issuer configuration.
- If the issuer module is missing, rebuild with xcaddy including the plugin, or switch to a built-in issuer (acme, internal, zerossl).
- Cross-check the issuer's JSON keys against the docs for your exact Caddy version.
- Simplify: reproduce with a minimal policy containing only the failing issuer to isolate the bad option.
Example fix
// before: unknown issuer module
"issuers": [{"module": "my-issuer", "key": "value"}]
// after
"issuers": [{"module": "acme", "email": "you@example.com"}] Defensive patterns
Strategy: try-catch
Try / catch
if err := policy.Provision(tlsApp); err != nil {
if strings.Contains(err.Error(), "loading TLS automation management module") {
return fmt.Errorf("review policy issuers config: %w", err)
}
} Prevention
- Prefer built-in issuer modules (acme, internal, zerossl) unless a plugin is required.
- Pin issuer module JSON to documented keys for your Caddy version.
- Use `caddy adapt` + `caddy validate` to catch issuer config errors pre-deploy.
When it happens
Trigger: Configuring "issuers" in a TLS automation policy with a module name not compiled in, malformed issuer JSON, or an issuer whose Provision rejects its options (e.g. invalid CA URL, missing email for ZeroSSL).
Common situations: JSON configs referencing issuer modules after switching to a stock Caddy build lacking a plugin; typos like "module": "acme" vs "acmez"; issuer sub-options renamed between Caddy versions.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- expanding email address '%s': %v
- DNS challenge enabled, but no DNS provider configured
- network_proxy module is not `(func(*http.Request) (*url.URL,
- your email address is required to use ZeroSSL's ACME endpoin
- failed getting EAB credentials: HTTP %d: %s (code %d)
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/dbc26a2e7bef9a57.
Report an issue: GitHub.