{"record":{"id":"7147b9a29cdd19b1","repo":"caddyserver/caddy","slug":"no-certificates-matched-custom-selection-policy","errorCode":null,"errorMessage":"no certificates matched custom selection policy","messagePattern":"no certificates matched custom selection policy","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/certselection.go","lineNumber":110,"sourceCode":"\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif len(p.AllTags) > 0 {\n\t\t\tfor _, tag := range p.AllTags {\n\t\t\t\tif !cert.HasTag(tag) {\n\t\t\t\t\tcontinue nextChoice\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// this certificate at least meets the policy's requirements,\n\t\t// but we still have to check expiration and compatibility\n\t\tviable = append(viable, cert)\n\t}\n\n\tif len(viable) == 0 {\n\t\treturn certmagic.Certificate{}, fmt.Errorf(\"no certificates matched custom selection policy\")\n\t}\n\n\treturn certmagic.DefaultCertificateSelector(hello, viable)\n}\n\n// UnmarshalCaddyfile sets up the CustomCertSelectionPolicy from Caddyfile tokens. Syntax:\n//\n//\tcert_selection {\n//\t\tall_tags             <values...>\n//\t\tany_tag              <values...>\n//\t\tpublic_key_algorithm <dsa|ecdsa|rsa>\n//\t\tserial_number        <big_integers...>\n//\t\tsubject_organization <values...>\n//\t}\nfunc (p *CustomCertSelectionPolicy) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {\n\t_, wrapper := d.Next(), d.Val() // consume wrapper name\n\n\t// No same-line options are supported","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/certselection.go#L92-L128","documentation":"Returned by CustomCertSelectionPolicy.SelectCertificate when at least one certificate was loaded but none satisfied every configured filter (tags, serial numbers, key algorithm, etc.). This is a certificate-choice failure inside certmagic after viable filtering, distinct from 'no certs loaded at all'.","triggerScenarios":"A cert_selection block with all_tags/any_tag/serial_number/public_key_algorithm filters that match zero of the loaded certificates; tags on certificates were renamed or removed in storage while the policy still references old names; an issuance renewal changed the serial number the policy pins.","commonSituations":"Operator configures cert_selection { any_tag prod } but certificates in storage were tagged differently (or not tagged); policy pinned a serial number and the cert was re-issued, changing it; ECDSA-only policy after migrating to RSA certs.","solutions":["List the loaded certificates and their tags/serials/alggorithms (e.g. inspect storage or 'caddy list-modules'-adjacent admin endpoints) and compare against the cert_selection filters","Fix the filter values to match reality (correct tag name, current serial, right algorithm)","Remove or widen overly strict filters (any_tag instead of all_tags) if intent is best-effort selection","If certificates were meant to be tagged, re-tag them at load/issuance time and reload"],"exampleFix":"# before\ncert_selection {\n\tany_tag staging\n}\n\n# after (certificates in storage are tagged \"prod\")\ncert_selection {\n\tany_tag prod\n}","handlingStrategy":"validation","validationCode":"// Pre-flight: assert at least one loaded cert satisfies the tag filter\nfunc anyCertMatches(certs []certmagic.Certificate, tags []string) bool {\n\tfor _, c := range certs {\n\t\tfor _, want := range tags {\n\t\t\tif c.HasTag(want) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define tag names once (in a shared variable/pipeline) and use them for both tagging and cert_selection","Prefer any_tag over all_tags unless multiple tags are genuinely required","Avoid pinning serial numbers in long-lived configs since reissuance changes them","After reissuing or re-tagging certs, reload Caddy and smoke-test one handshake per policy"],"tags":["caddy","tls","certificates","cert-selection","configuration"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}