caddyserver/caddy · error

no server identity configured

Error message

no server identity configured

What it means

Context.IdentityCredentials returns TLS client certificates for this instance's managed identity, used when Caddy acts as a TLS client to another Caddy remote admin. It errors when there is no config, no admin section, or no admin.identity configured — i.e. the caller asked for identity credentials on a Context whose config never set them.

Source

Thrown at admin.go:651

		Issuers: ident.issuers,
	}
	if makeCache {
		identityCertCache = certmagic.NewCache(certmagic.CacheOptions{
			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 {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Configure admin.identity with identifiers (and issuers if the default ACME issuer is unsuitable) in the running config
  2. Guard the call: only request identity credentials when cfg has an identity configured, or treat the error as 'feature disabled'
  3. For lab setups, use the internal issuer to avoid external dependencies
Defensive patterns

Strategy: try-catch

Try / catch

creds, err := ctx.IdentityCredentials(logger)
if err != nil {
    if strings.Contains(err.Error(), "no server identity configured") {
        // identity feature not enabled in this config; skip client-cert auth
        creds = nil
    } else {
        return err
    }
}

Prevention

When it happens

Trigger: Calling ctx.IdentityCredentials(...) from a module when the running config has no admin.identity; using the identity feature of reverse_proxy to another admin endpoint without configuring identity; config loaded via API where admin was replaced.

Common situations: Modules (e.g. layer4 or reverse_proxy transport) that dial a remote Caddy admin API and request client credentials; developers testing modules with minimal configs that omit admin.

Related errors


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