{"record":{"id":"6a8b2d3c40b1562f","repo":"caddyserver/caddy","slug":"two-policies-with-same-match-criteria-have-conflic-6a8b2d","errorCode":null,"errorMessage":"two policies with same match criteria have conflicting default SNI: %s vs. %s","messagePattern":"two policies with same match criteria have conflicting default SNI: (.+?) vs\\. (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"caddyconfig/httpcaddyfile/httptype.go","lineNumber":1278,"sourceCode":"\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting cipher suites: %v vs. %v\",\n\t\t\t\t\t\tcps[i].CipherSuites, cps[j].CipherSuites)\n\t\t\t\t}\n\t\t\t\tif cps[i].ClientAuthentication == nil &&\n\t\t\t\t\tcps[j].ClientAuthentication != nil &&\n\t\t\t\t\t!reflect.DeepEqual(cps[i].ClientAuthentication, cps[j].ClientAuthentication) {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting client auth configuration: %+v vs. %+v\",\n\t\t\t\t\t\tcps[i].ClientAuthentication, cps[j].ClientAuthentication)\n\t\t\t\t}\n\t\t\t\tif len(cps[i].Curves) > 0 &&\n\t\t\t\t\tlen(cps[j].Curves) > 0 &&\n\t\t\t\t\t!reflect.DeepEqual(cps[i].Curves, cps[j].Curves) {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting curves: %v vs. %v\",\n\t\t\t\t\t\tcps[i].Curves, cps[j].Curves)\n\t\t\t\t}\n\t\t\t\tif cps[i].DefaultSNI != \"\" &&\n\t\t\t\t\tcps[j].DefaultSNI != \"\" &&\n\t\t\t\t\tcps[i].DefaultSNI != cps[j].DefaultSNI {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting default SNI: %s vs. %s\",\n\t\t\t\t\t\tcps[i].DefaultSNI, cps[j].DefaultSNI)\n\t\t\t\t}\n\t\t\t\tif cps[i].FallbackSNI != \"\" &&\n\t\t\t\t\tcps[j].FallbackSNI != \"\" &&\n\t\t\t\t\tcps[i].FallbackSNI != cps[j].FallbackSNI {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting fallback SNI: %s vs. %s\",\n\t\t\t\t\t\tcps[i].FallbackSNI, cps[j].FallbackSNI)\n\t\t\t\t}\n\t\t\t\tif cps[i].ProtocolMin != \"\" &&\n\t\t\t\t\tcps[j].ProtocolMin != \"\" &&\n\t\t\t\t\tcps[i].ProtocolMin != cps[j].ProtocolMin {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting min protocol: %s vs. %s\",\n\t\t\t\t\t\tcps[i].ProtocolMin, cps[j].ProtocolMin)\n\t\t\t\t}\n\t\t\t\tif cps[i].ProtocolMax != \"\" &&\n\t\t\t\t\tcps[j].ProtocolMax != \"\" &&\n\t\t\t\t\tcps[i].ProtocolMax != cps[j].ProtocolMax {\n\t\t\t\t\treturn nil, fmt.Errorf(\"two policies with same match criteria have conflicting max protocol: %s vs. %s\",","sourceCodeStart":1260,"sourceCodeEnd":1296,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/httpcaddyfile/httptype.go#L1260-L1296","documentation":"Two connection policies with identical match criteria both set a non-empty DefaultSNI and the values differ. DefaultSNI decides which certificate to serve when a client sends no SNI; two different defaults for the same matched connections are irreconcilable.","triggerScenarios":"The global `default_sni` option combined with a site block or connection policy that sets a different default_sni for the same server — e.g. `{ default_sni a.example.com }` globally while a `tls { default_sni b.example.com }` style policy on matching names produces a second policy with the same matchers.","commonSituations":"Setting default_sni both globally and per-site (or in multiple imported snippets) with inconsistent values that end up on one server.","solutions":["Set default_sni in exactly one place (prefer the global option) and delete per-site duplicates","Align the values if both are intentional","Use separate servers per listen address if different defaults are truly needed"],"exampleFix":"# before\n{\n  default_sni a.example.com\n}\nexample.com {\n  # snippet also sets default_sni b.example.com\n}\n# after\n{\n  default_sni a.example.com\n}\nexample.com {\n  respond \"ok\"\n}","handlingStrategy":"validation","validationCode":"# Exactly one default_sni source\nassert count_of_default_sni_declarations(config) <= 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set default_sni only in the global options","Do not copy default_sni into imported snippets","Grep configs for default_sni before merging files"],"tags":["caddy","tls","sni","caddyfile","conflict"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}