caddyserver/caddy · error

loading identity issuer modules: %s

Error message

loading identity issuer modules: %s

What it means

Raised during admin identity configuration when ctx.LoadModule fails to load/provision the configured identity issuer modules (cfg.Admin.Identity.IssuersRaw). The inner error usually names the exact module and problem — unknown module name, invalid issuer JSON, or issuer provisioning failure. Defaults to an 'acme' issuer if none configured.

Source

Thrown at admin.go:478

// manageIdentity sets up automated identity management for this server.
func manageIdentity(ctx Context, cfg *Config) error {
	if cfg == nil || cfg.Admin == nil || cfg.Admin.Identity == nil {
		return nil
	}

	// set default issuers; this is pretty hacky because we can't
	// import the caddytls package -- but it works
	if cfg.Admin.Identity.IssuersRaw == nil {
		cfg.Admin.Identity.IssuersRaw = []json.RawMessage{
			json.RawMessage(`{"module": "acme"}`),
		}
	}

	// load and provision issuer modules
	if cfg.Admin.Identity.IssuersRaw != nil {
		val, err := ctx.LoadModule(cfg.Admin.Identity, "IssuersRaw")
		if err != nil {
			return fmt.Errorf("loading identity issuer modules: %s", err)
		}
		for _, issVal := range val.([]any) {
			cfg.Admin.Identity.issuers = append(cfg.Admin.Identity.issuers, issVal.(certmagic.Issuer))
		}
	}

	// we'll make a new cache when we make the CertMagic config, so stop any previous cache
	if identityCertCache != nil {
		identityCertCache.Stop()
	}

	logger := Log().Named("admin.identity")
	cmCfg := cfg.Admin.Identity.certmagicConfig(logger, true)

	// issuers have circular dependencies with the configs because,
	// as explained in the caddytls package, they need access to the
	// correct storage and cache to solve ACME challenges
	for _, issuer := range cfg.Admin.Identity.issuers {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Inspect the wrapped error — it identifies which issuer module and why it failed
  2. Verify each issuer object has a valid 'module' key matching a registered issuer (e.g. 'acme', 'internal', 'zerossl')
  3. For plugin issuers, rebuild with xcaddy ensuring the plugin is included and compatible
  4. Simplify: omit issuers_raw to use the default ACME identity issuer and see if the error disappears
Defensive patterns

Strategy: try-catch

Validate before calling

var knownIssuers = map[string]bool{"acme": true, "internal": true, "zerossl": true}

func validateIdentityIssuers(cfg []json.RawMessage) error {
	for _, raw := range cfg {
		var probe struct{ Module string `json:"module"` }
		if err := json.Unmarshal(raw, &probe); err != nil {
			return fmt.Errorf("issuer JSON invalid: %v", err)
		}
		if !knownIssuers[probe.Module] {
			return fmt.Errorf("unknown issuer module %q (is the plugin built in?)", probe.Module)
		}
	}
	return nil
}

Prevention

When it happens

Trigger: Configuring admin.identity with a custom issuers array in JSON where the 'module' field names a nonexistent issuer; malformed issuer JSON; an ACME issuer whose Provision fails (e.g. invalid fields); custom issuer plugins not compiled into the binary.

Common situations: Using the experimental remote admin feature with identity issuers; typo in module name ('acme' vs 'acme_dns'); plugin modules missing from custom builds; schema changes between Caddy versions.

Related errors


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