{"record":{"id":"0a044ded1e70210d","repo":"caddyserver/caddy","slug":"cannot-enable-remote-admin-without-a-certificate-c","errorCode":null,"errorMessage":"cannot enable remote admin without a certificate cache; configure identity management to initialize a certificate cache","messagePattern":"cannot enable remote admin without a certificate cache; configure identity management to initialize a certificate cache","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"admin.go","lineNumber":561,"sourceCode":"\t}\n\n\t// create client certificate pool for TLS mutual auth, and extract public keys\n\t// so that we can enforce access controls at the application layer\n\tclientCertPool := x509.NewCertPool()\n\tfor i, accessControl := range cfg.Admin.Remote.AccessControl {\n\t\tfor j, certBase64 := range accessControl.PublicKeys {\n\t\t\tcert, err := decodeBase64DERCert(certBase64)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"access control %d public key %d: parsing base64 certificate DER: %v\", i, j, err)\n\t\t\t}\n\t\t\taccessControl.publicKeys = append(accessControl.publicKeys, cert.PublicKey)\n\t\t\tclientCertPool.AddCert(cert)\n\t\t}\n\t}\n\n\t// create TLS config that will enforce mutual authentication\n\tif identityCertCache == nil {\n\t\treturn fmt.Errorf(\"cannot enable remote admin without a certificate cache; configure identity management to initialize a certificate cache\")\n\t}\n\tcmCfg := cfg.Admin.Identity.certmagicConfig(remoteLogger, false)\n\ttlsConfig := cmCfg.TLSConfig()\n\ttlsConfig.NextProtos = nil // this server does not solve ACME challenges\n\ttlsConfig.ClientAuth = tls.RequireAndVerifyClientCert\n\ttlsConfig.ClientCAs = clientCertPool\n\n\t// convert logger to stdlib so it can be used by HTTP server\n\tserverLogger, err := zap.NewStdLogAt(remoteLogger, zap.DebugLevel)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tserverMu.Lock()\n\t// create secure HTTP server\n\tremoteAdminServer = &http.Server{\n\t\tAddr:              addr.String(), // for logging purposes only\n\t\tHandler:           handler,","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L543-L579","documentation":"Enabling admin.remote requires server identity management because the remote endpoint's TLS certificate comes from the identity certmagic cache (identityCertCache). If that package-level cache is nil — i.e. admin.identity did not run and configure a certificate cache — remote admin cannot be set up and startup fails with this error.","triggerScenarios":"JSON config with admin.remote configured but no admin.identity section (or identity provisioning skipped/failed silently in this path); ordering issues where remote setup runs before identity setup in the same config load.","commonSituations":"Experimenting with remote admin and adding only the remote block; copying partial examples from docs; identity issuers left empty in a config that still requests remote access.","solutions":["Add an admin.identity section to the same config (at minimum identifiers, letting the default ACME or internal issuer manage a certificate)","Consider the 'internal' issuer for identity to avoid external ACME dependencies: {\"module\": \"internal\"}","Verify the whole admin config with caddy validate before restart","If you don't need remote admin, remove the admin.remote block"],"exampleFix":"// before\n\"admin\": {\n  \"remote\": { \"listen\": \":2021\", \"access_control\": [...] }\n}\n\n// after\n\"admin\": {\n  \"identity\": {\n    \"identifiers\": [\"admin.example.com\"],\n    \"issuers\": [{\"module\": \"internal\"}]\n  },\n  \"remote\": { \"listen\": \":2021\", \"access_control\": [...] }\n}","handlingStrategy":"validation","validationCode":"func remoteAdminConfigComplete(cfg *Config) error {\n\tif cfg.Admin != nil && cfg.Admin.Remote != nil {\n\t\tif cfg.Admin.Identity == nil || len(cfg.Admin.Identity.Identifiers) == 0 {\n\t\t\treturn errors.New(\"admin.remote requires admin.identity with identifiers\")\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat admin.remote and admin.identity as one unit in config templates","Validate configs in CI before deploy","Use the internal issuer for identity in closed environments"],"tags":["admin-api","remote-admin","identity","configuration","tls"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}