{"record":{"id":"821f5ed5dd63df6b","repo":"caddyserver/caddy","slug":"no-server-tls-configuration-available-for-clienthe","errorCode":null,"errorMessage":"no server TLS configuration available for ClientHello: %+v","messagePattern":"no server TLS configuration available for ClientHello: %\\+v","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/connpolicy.go","lineNumber":139,"sourceCode":"\t\tpossiblePolicies := cp\n\t\tif indexedPolicies, ok := indexedBySNI[asciiServerNameForMatch(hello.ServerName)]; ok {\n\t\t\tpossiblePolicies = indexedPolicies\n\t\t}\n\n\tpolicyLoop:\n\t\tfor _, pol := range possiblePolicies {\n\t\t\tfor _, matcher := range pol.matchers {\n\t\t\t\tif !matcher.Match(hello) {\n\t\t\t\t\tcontinue policyLoop\n\t\t\t\t}\n\t\t\t}\n\t\t\tif pol.Drop {\n\t\t\t\treturn nil, fmt.Errorf(\"dropping connection\")\n\t\t\t}\n\t\t\treturn pol.TLSConfig, nil\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"no server TLS configuration available for ClientHello: %+v\", hello)\n\t}\n\n\ttlsCfg := &tls.Config{\n\t\tMinVersion:         tls.VersionTLS12,\n\t\tGetConfigForClient: getConfigForClient,\n\t}\n\n\t// enable ECH, if configured\n\tif tlsAppIface, err := ctx.AppIfConfigured(\"tls\"); err == nil {\n\t\ttlsApp := tlsAppIface.(*TLS)\n\n\t\tif tlsApp.EncryptedClientHello != nil && len(tlsApp.EncryptedClientHello.configs) > 0 {\n\t\t\t// if no publication was configured, we apply ECH to all server names by default,\n\t\t\t// but the TLS app needs to know what they are in this case, since they don't appear\n\t\t\t// in its config (remember, TLS connection policies are used by *other* apps to\n\t\t\t// run TLS servers) -- we skip names with placeholders\n\t\t\tif tlsApp.EncryptedClientHello.Publication == nil {\n\t\t\t\trepl := caddy.NewReplacer()","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/connpolicy.go#L121-L157","documentation":"Returned by the GetConfigForClient callback when a ClientHello arrived that no connection policy matched (and no default policy applied). The %+v payload dumps the whole ClientHelloInfo (server name, supported versions, ALPN, cipher suites, remote address), which is the key diagnostic: it shows exactly what the client asked for.","triggerScenarios":"ServerName-based policy index miss: the ClientHello's SNI is absent from all policies and no catch-all policy exists; client sends no SNI while all policies require sni matching; wildcards that do not cover the requested name (e.g. policy for *.example.com and client asks a.b.example.com).","commonSituations":"New domain pointed at the server but not added to the config; clients connecting by IP (empty SNI); a policy list tightened so the default fallback was removed; multi-level subdomain not covered by a single-level wildcard.","solutions":["Look at the ServerName in the dumped ClientHello and compare it to the matchers (sni values) of each policy","Add a policy (or site block) covering that name, or a final catch-all policy","For SNI-less clients (IP connections), add a policy matching on no-SNI or set a default SNI","For deep subdomains, add explicit names or restructure matching since *.example.com does not match a.b.example.com"],"exampleFix":"# before\nexample.com {\n\ttls {\n\t\tpolicies {\n\t\t\tpolicy {\n\t\t\t\tmatch { sni example.com }\n\t\t\t}\n\t\t}\n\t}\n}\n\n# after (catch-all for anything else)\nexample.com {\n\ttls {\n\t\tpolicies {\n\t\t\tpolicy {\n\t\t\t\tmatch { sni example.com }\n\t\t\t}\n\t\t\tpolicy {\n\t\t\t\tmatch { sni * }\n\t\t\t}\n\t\t}\n\t}\n}","handlingStrategy":"validation","validationCode":"# Enumerate SNIs your policies cover and diff against expected hostnames:\ncaddy adapt --config Caddyfile --adapter caddyfile 2>/dev/null \\\n  | grep -o '\"sni\"[^}]*}' | sort -u","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include a final catch-all policy (or default site) if unknown SNIs should get a response instead of an error","Remember single-level wildcards (*.example.com) do not match multi-level subdomains","Log and review the ClientHello dump in the error — the ServerName field tells you exactly what to allow"],"tags":["caddy","tls","sni","connection-policy","handshake"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}