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

  1. Read the wrapped error (%s) — it names the failing issuer and cause; correct the issuer configuration.
  2. If the issuer module is missing, rebuild with xcaddy including the plugin, or switch to a built-in issuer (acme, internal, zerossl).
  3. Cross-check the issuer's JSON keys against the docs for your exact Caddy version.
  4. 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

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

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/dbc26a2e7bef9a57. Report an issue: GitHub.