caddyserver/caddy · error

no identifiers configured

Error message

no identifiers configured

What it means

IdentityCredentials rejects an admin.identity section that exists but has an empty identifiers list. Identifiers (SANs) are required because certmagic must know which names to obtain credentials for; without them, magic.ClientCredentials cannot request any certificate.

Source

Thrown at admin.go:655

			GetConfigForCert: func(certmagic.Certificate) (*certmagic.Config, error) {
				return cmCfg, nil
			},
			Logger: logger.Named("cache"),
		})
	}
	cmCfg = certmagic.New(identityCertCache, template)
	return cmCfg
}

// IdentityCredentials returns this instance's configured, managed identity credentials
// that can be used in TLS client authentication.
func (ctx Context) IdentityCredentials(logger *zap.Logger) ([]tls.Certificate, error) {
	if ctx.cfg == nil || ctx.cfg.Admin == nil || ctx.cfg.Admin.Identity == nil {
		return nil, fmt.Errorf("no server identity configured")
	}
	ident := ctx.cfg.Admin.Identity
	if len(ident.Identifiers) == 0 {
		return nil, fmt.Errorf("no identifiers configured")
	}
	if logger == nil {
		logger = Log()
	}
	magic := ident.certmagicConfig(logger, false)
	return magic.ClientCredentials(ctx, ident.Identifiers)
}

// enforceAccessControls enforces application-layer access controls for r based on remote.
// It expects that the TLS server has already established at least one verified chain of
// trust, and then looks for a matching, authorized public key that is allowed to access
// the defined path(s) using the defined method(s).
func (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {
	for _, chain := range r.TLS.VerifiedChains {
		for _, peerCert := range chain {
			for _, adminAccess := range remote.AccessControl {
				for _, allowedKey := range adminAccess.publicKeys {
					// see if we found a matching public key; the TLS server already verified the chain

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Add at least one identifier: "identifiers": ["host.example.com"] matching the name peers will verify
  2. Ensure the identifiers array is not empty after templating/rendering
  3. Validate the config with caddy validate before deploying

Example fix

// before
"identity": { "issuers": [{"module": "internal"}] }

// after
"identity": {
  "identifiers": ["caddy-node1.internal"],
  "issuers": [{"module": "internal"}]
}
Defensive patterns

Strategy: validation

Validate before calling

func identityHasIdentifiers(cfg *Config) bool {
	return cfg != nil && cfg.Admin != nil && cfg.Admin.Identity != nil &&
		len(cfg.Admin.Identity.Identifiers) > 0
}

Prevention

When it happens

Trigger: admin.identity: {} present in JSON with no 'identifiers' array, or an empty array; config templates that scaffold identity but never fill in names.

Common situations: Copied identity examples with placeholders removed; automation that emits the identity object conditionally and leaves identifiers unset.

Related errors


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