kubernetes/kops · error
root certificate pool is required
Error message
root certificate pool is required
What it means
Guard error: verifyAttestedDocumentWithRootAndFetcher was invoked with a nil root certificate pool, so there is no trust anchor to verify the attestation chain against. A programming/configuration error in the caller, not attacker-triggered input.
Source
Thrown at upup/pkg/fi/cloudup/azure/attest.go:186
return fetchIntermediateCertsFromBaseURL(a.client, microsoftIntermediateCertBaseURL, signer)
}
// verifyAttestedDocumentWithRootAndFetcher verifies a PKCS7 attested document using the supplied
// root pool and intermediate fetcher.
//
// The trust progression is:
// 1. parseAndValidatePKCS7Signer verifies the PKCS7 self-signature against the embedded leaf
// certificate. At this point the signed content is integrity-bound to the leaf, but the
// leaf itself is still untrusted — its chain to a root has not been built. The leaf's SAN
// is sanity-checked against the Azure metadata domains here too.
// 2. parseAndValidateAttestedDocumentContent parses the now-integrity-checked signed content
// for cheap rejection-only checks (nonce binding, freshness) before paying for chain
// building or network fetches.
// 3. verifySignerCertChain performs the actual cryptographic chain validation against
// rootCertPool. This is the call that establishes trust in the signer.
func verifyAttestedDocumentWithRootAndFetcher(signature string, body []byte, rootCertPool *x509.CertPool, fetchIntermediates func(*x509.Certificate) (*x509.CertPool, error)) (*attestedData, error) {
if rootCertPool == nil {
return nil, fmt.Errorf("root certificate pool is required")
}
p7, signer, err := parseAndValidatePKCS7Signer(signature)
if err != nil {
return nil, err
}
// The signature binds this content to the (still-untrusted) leaf, so it is safe to run
// rejection-only checks (nonce, freshness) before paying for chain building or network fetches
// below.
data, err := parseAndValidateAttestedDocumentContent(p7.Content, body)
if err != nil {
return nil, err
}
// Verify using only the certificates embedded in the PKCS7 structure; if that succeeds, the signer
// is trusted. If it fails but the PKCS7 already embeds a cert matching the signer's issuer, the
// chain is genuinely broken (not just missing an intermediate), so fail fast instead of fetching.View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the verifier is built via newAttestationVerifier, which always supplies a root pool
- Fix the caller to pass a non-nil *x509.CertPool of trusted Microsoft roots
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at upup/pkg/fi/cloudup/azure/attest.go:186 when the library encounters an invalid state.
Common situations: See trigger scenarios.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/311e3064357f52bb.
Report an issue: GitHub.