{"record":{"id":"76d2987cb2474d09","repo":"kubernetes/kops","slug":"no-fetched-intermediate-certificates-matched-signe","errorCode":null,"errorMessage":"no fetched intermediate certificates matched signer issuer %q","messagePattern":"no fetched intermediate certificates matched signer issuer %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/attest.go","lineNumber":417,"sourceCode":"\t\tfor _, url := range urls {\n\t\t\tklog.V(2).Infof(\"Fetching intermediate certificate from %s\", url)\n\t\t\tcert, err := fetchCertificate(client, url)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := validateFetchedIntermediateForSigner(current, cert); err != nil {\n\t\t\t\tklog.V(2).Infof(\"Fetched intermediate certificate from %s did not match issuer: %v\", url, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tklog.V(2).Infof(\"Fetched intermediate certificate from %s matched issuer\", url)\n\t\t\tpool.AddCert(cert)\n\t\t\tif issuer == nil {\n\t\t\t\tissuer = cert\n\t\t\t}\n\t\t}\n\t\tif issuer == nil {\n\t\t\tif hop == 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"no fetched intermediate certificates matched signer issuer %q\", signer.Issuer)\n\t\t\t}\n\t\t\t// Fetched, but nothing matched current's issuer; stop with what we have.\n\t\t\tbreak\n\t\t}\n\t\tcurrent = issuer\n\t}\n\n\treturn pool, nil\n}\n\n// fetchCertificate fetches and parses a DER-encoded certificate from the given URL.\nfunc fetchCertificate(client *http.Client, url string) (*x509.Certificate, error) {\n\tresp, err := client.Get(url)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fetching intermediate certificate from %s: %w\", url, err)\n\t}\n\tdefer resp.Body.Close()\n","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/attest.go#L399-L435","documentation":"On the first hop of the AIA chain walk, fetchIntermediateCertsFromBaseURL expects at least one fetched certificate whose subject matches the signer's issuer. If none of the certificates retrieved from the signer's AIA URL match, the walk cannot make progress and this error is thrown — the fetched material would not form a valid chain and must not be used or cached.","triggerScenarios":"The signer's AIA URL returns certificates that do not match signer.Issuer (wrong CA endpoint, re-issued signer with a new issuer, or an endpoint serving unrelated certificates) and hop == 0.","commonSituations":"CA migrated to a new intermediate and cached/old signer certificates still reference the previous issuer; misconfigured or mocked AIA endpoints in tests; man-in-the-middle or proxy serving wrong content; Microsoft rotating intermediates.","solutions":["Confirm the signer's AIA URL is the correct, current CA issuance endpoint","Re-fetch the leaf/signer certificate so its AIA points to the current issuing CA","Check that no proxy or custom baseURL is intercepting and altering the fetched certificates","Update the base URL / allowlist if the CA vendor changed its intermediate hierarchy"],"exampleFix":"// before\nbaseURL := \"https://old-aia.example.com/\" // stale CA endpoint\npool, err := fetchIntermediateCerts(clientWithBaseURL(baseURL), signer)\n// after\nbaseURL := signer.AIAEndpoint() // use the AIA URL embedded in the current signer\npool, err := fetchIntermediateCerts(clientWithBaseURL(baseURL), signer)","handlingStrategy":"fallback","validationCode":"// Sanity-check that the signer has an issuer name and an AIA URL before the walk\nif signer == nil || signer.Issuer == nil || len(signer.OCSPServer) == 0 && len(signer.IssuingCertificateURL) == 0 {\n    return nil, fmt.Errorf(\"signer %v lacks usable issuer/AIA info\", signer)\n}","typeGuard":"func signerHasAIA(c *x509.Certificate) bool {\n    return c != nil && len(c.IssuingCertificateURL) > 0\n}","tryCatchPattern":"pool, err := fetchIntermediateCerts(client, signer)\nif err != nil && strings.Contains(err.Error(), \"no fetched intermediate certificates matched\") {\n    // fall back to system intermediate pool or re-fetch a current signer certificate\n    return verifyWithSystemIntermediates(signer)\n}","preventionTips":["Re-fetch leaf/signer certificates after CA intermediate rotations","Pin or allowlist the correct current Microsoft CA AIA endpoints","Test chain walking against live or recorded AIA responses periodically"],"tags":["azure","tls","certificates","aia","chain-mismatch"],"backgroundTag":"intermediate-certificate-mismatch","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}