{"record":{"id":"6c1097136c487d86","repo":"caddyserver/caddy","slug":"no-server-identity-configured","errorCode":null,"errorMessage":"no server identity configured","messagePattern":"no server identity configured","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"admin.go","lineNumber":651,"sourceCode":"\t\tIssuers: ident.issuers,\n\t}\n\tif makeCache {\n\t\tidentityCertCache = certmagic.NewCache(certmagic.CacheOptions{\n\t\t\tGetConfigForCert: func(certmagic.Certificate) (*certmagic.Config, error) {\n\t\t\t\treturn cmCfg, nil\n\t\t\t},\n\t\t\tLogger: logger.Named(\"cache\"),\n\t\t})\n\t}\n\tcmCfg = certmagic.New(identityCertCache, template)\n\treturn cmCfg\n}\n\n// IdentityCredentials returns this instance's configured, managed identity credentials\n// that can be used in TLS client authentication.\nfunc (ctx Context) IdentityCredentials(logger *zap.Logger) ([]tls.Certificate, error) {\n\tif ctx.cfg == nil || ctx.cfg.Admin == nil || ctx.cfg.Admin.Identity == nil {\n\t\treturn nil, fmt.Errorf(\"no server identity configured\")\n\t}\n\tident := ctx.cfg.Admin.Identity\n\tif len(ident.Identifiers) == 0 {\n\t\treturn nil, fmt.Errorf(\"no identifiers configured\")\n\t}\n\tif logger == nil {\n\t\tlogger = Log()\n\t}\n\tmagic := ident.certmagicConfig(logger, false)\n\treturn magic.ClientCredentials(ctx, ident.Identifiers)\n}\n\n// enforceAccessControls enforces application-layer access controls for r based on remote.\n// It expects that the TLS server has already established at least one verified chain of\n// trust, and then looks for a matching, authorized public key that is allowed to access\n// the defined path(s) using the defined method(s).\nfunc (remote RemoteAdmin) enforceAccessControls(r *http.Request) error {\n\tfor _, chain := range r.TLS.VerifiedChains {","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L633-L669","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Configure admin.identity with identifiers (and issuers if the default ACME issuer is unsuitable) in the running config","Guard the call: only request identity credentials when cfg has an identity configured, or treat the error as 'feature disabled'","For lab setups, use the internal issuer to avoid external dependencies"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"creds, err := ctx.IdentityCredentials(logger)\nif err != nil {\n    if strings.Contains(err.Error(), \"no server identity configured\") {\n        // identity feature not enabled in this config; skip client-cert auth\n        creds = nil\n    } else {\n        return err\n    }\n}","preventionTips":["Check for an admin.identity section before requesting identity credentials","In embedded/module code, degrade gracefully when identity is absent","Keep identity config present in all nodes that must mutually authenticate"],"tags":["admin-api","identity","tls-client","modules"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}