{"record":{"id":"2d827264c689a4d5","repo":"caddyserver/caddy","slug":"on-demand-tls-config-conflict-both-ask-endpoint","errorCode":null,"errorMessage":"on-demand TLS config conflict: both 'ask' endpoint and a 'permission' module are specified; 'ask' is deprecated, so use only the permission module","messagePattern":"on-demand TLS config conflict: both 'ask' endpoint and a 'permission' module are specified; 'ask' is deprecated, so use only the permission module","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/tls.go","lineNumber":280,"sourceCode":"\tcertCacheMu.RUnlock()\n\tfor _, loader := range t.certificateLoaders {\n\t\tcerts, err := loader.LoadCertificates()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"loading certificates: %v\", err)\n\t\t}\n\t\tfor _, cert := range certs {\n\t\t\thash, err := magic.CacheUnmanagedTLSCertificate(ctx, cert.Certificate, cert.Tags)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"caching unmanaged certificate: %v\", err)\n\t\t\t}\n\t\t\tt.loaded[hash] = \"\"\n\t\t}\n\t}\n\n\t// on-demand permission module\n\tif t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.PermissionRaw != nil {\n\t\tif t.Automation.OnDemand.Ask != \"\" {\n\t\t\treturn fmt.Errorf(\"on-demand TLS config conflict: both 'ask' endpoint and a 'permission' module are specified; 'ask' is deprecated, so use only the permission module\")\n\t\t}\n\t\tval, err := ctx.LoadModule(t.Automation.OnDemand, \"PermissionRaw\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"loading on-demand TLS permission module: %v\", err)\n\t\t}\n\t\tt.Automation.OnDemand.permission = val.(OnDemandPermission)\n\t}\n\n\t// automation/management policies\n\tif t.Automation == nil {\n\t\tt.Automation = new(AutomationConfig)\n\t}\n\tt.Automation.defaultPublicAutomationPolicy = new(AutomationPolicy)\n\terr = t.Automation.defaultPublicAutomationPolicy.Provision(t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"provisioning default public automation policy: %v\", err)\n\t}\n\tfor n := range t.automateNames {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/tls.go#L262-L298","documentation":"On-demand TLS supports two permission mechanisms: the deprecated 'ask' endpoint URL and the newer 'permission' module. When tls.automation.on_demand sets both 'ask' and a 'permission' module, Caddy refuses to guess which applies and aborts provisioning. 'ask' is deprecated in favor of the http permission module, which supersedes it.","triggerScenarios":"JSON config containing {\"on_demand\": {\"ask\": \"http://...\", \"permission\": {...}}} — both keys non-empty under tls.automation.on_demand. In Caddyfile terms, combining the legacy 'ask' global option with an 'on_demand_tls permission' block.","commonSituations":"Configs migrated from older Caddy versions that already had 'ask' and then added a permission module per new docs; copy-pasting examples from different documentation eras into one config.","solutions":["Delete the 'ask' entry and keep only the permission module (e.g. permission module 'http' with endpoint set to the old ask URL)","If you must keep 'ask' temporarily, remove the 'permission' block entirely","Run 'caddy validate' after editing to confirm the conflict is gone"],"exampleFix":"// before\n\"on_demand\": {\"ask\": \"http://localhost:5555/check\", \"permission\": {\"module\": \"http\", \"endpoint\": \"http://localhost:5555/check\"}}\n// after\n\"on_demand\": {\"permission\": {\"module\": \"http\", \"endpoint\": \"http://localhost:5555/check\"}}","handlingStrategy":"validation","validationCode":"jq '.apps.tls.automation.on_demand // {} | select(.ask != null and .permission != null)' Caddyfile.json\n# non-empty output means the conflict will abort provisioning","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never combine 'ask' with 'permission'; migrate fully to the permission module","Add a config lint step that rejects on_demand blocks containing both keys"],"tags":["caddy","tls","on-demand","config-conflict","deprecation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}