{"record":{"id":"506015bc07428e3e","repo":"caddyserver/caddy","slug":"automation-policy-d-cannot-apply-more-than-one-a","errorCode":null,"errorMessage":"automation policy %d: cannot apply more than one automation policy to host: %s (first match in policy %d)","messagePattern":"automation policy (.+?): cannot apply more than one automation policy to host: (.+?) \\(first match in policy (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/tls.go","lineNumber":386,"sourceCode":"// Validate validates t's configuration.\nfunc (t *TLS) Validate() error {\n\tif t.Automation != nil {\n\t\t// ensure that host aren't repeated; since only the first\n\t\t// automation policy is used, repeating a host in the lists\n\t\t// isn't useful and is probably a mistake; same for two\n\t\t// catch-all/default policies\n\t\tvar hasDefault bool\n\t\thostSet := make(map[string]int)\n\t\tfor i, ap := range t.Automation.Policies {\n\t\t\tif len(ap.subjects) == 0 {\n\t\t\t\tif hasDefault {\n\t\t\t\t\treturn fmt.Errorf(\"automation policy %d is the second policy that acts as default/catch-all, but will never be used\", i)\n\t\t\t\t}\n\t\t\t\thasDefault = true\n\t\t\t}\n\t\t\tfor _, h := range ap.subjects {\n\t\t\t\tif first, ok := hostSet[h]; ok {\n\t\t\t\t\treturn fmt.Errorf(\"automation policy %d: cannot apply more than one automation policy to host: %s (first match in policy %d)\", i, h, first)\n\t\t\t\t}\n\t\t\t\thostSet[h] = i\n\t\t\t}\n\t\t}\n\t}\n\tif t.Cache != nil {\n\t\tif t.Cache.Capacity < 0 {\n\t\t\treturn fmt.Errorf(\"cache capacity must be >= 0\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// Start activates the TLS module.\nfunc (t *TLS) Start() error {\n\t// warn if on-demand TLS is enabled but no restrictions are in place\n\tif t.Automation.OnDemand == nil || (t.Automation.OnDemand.Ask == \"\" && t.Automation.OnDemand.permission == nil) {\n\t\tfor _, ap := range t.Automation.Policies {","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/tls.go#L368-L404","documentation":"Policy matching is first-match-wins, so a host may only appear as a subject in one automation policy; a second policy listing the same host is silently ineffective. Validation builds a host->policy-index map and rejects duplicates, naming both the offending policy index and the earlier policy that already claimed the host.","triggerScenarios":"automation.policies = [{subjects: [\"example.com\"], ...}, {subjects: [\"example.com\", \"www.example.com\"], ...}] — example.com is claimed by policy 0, so policy 1 triggers the error.","commonSituations":"Splitting config snippets that each manage overlapping domains; merging site configs into policies without deduplicating; wildcard policies that also explicitly list a covered name in another policy.","solutions":["Keep each subject in exactly one policy; consolidate the settings for the duplicate host into the first policy that should own it","If different issuers are intended per-subdomain, split subjects precisely (e.g. move only www.example.com to the second policy)","Use 'caddy adapt' + inspect the JSON to see the final policy subjects after snippet imports"],"exampleFix":"// before\n\"policies\": [\n  {\"subjects\": [\"example.com\"], \"issuers\": [{\"module\": \"acme\"}]},\n  {\"subjects\": [\"example.com\", \"api.example.com\"], \"issuers\": [{\"module\": \"internal\"}]}\n]\n// after\n\"policies\": [\n  {\"subjects\": [\"example.com\"], \"issuers\": [{\"module\": \"acme\"}]},\n  {\"subjects\": [\"api.example.com\"], \"issuers\": [{\"module\": \"internal\"}]}\n]","handlingStrategy":"validation","validationCode":"seen := map[string]int{}\nfor i, p := range tlsApp.Automation.Policies {\n\tfor _, h := range p.SubjectsRaw {\n\t\tif first, dup := seen[h]; dup {\n\t\t\treturn fmt.Errorf(\"host %s in policies %d and %d\", h, first, i)\n\t\t}\n\t\tseen[h] = i\n\t}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one canonical policy per hostname; deduplicate after merging snippets","Inspect adapted JSON ('caddy adapt --pretty') to see effective subject lists"],"tags":["caddy","tls","automation-policy","validation","duplicate-subject"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}