kubernetes/kops · error
signer certificate is required
Error message
signer certificate is required
What it means
intermediateCertPoolWithCaches builds an x509.CertPool of intermediate certificates keyed by the signer certificate, using positive/negative TTL caches. The signer certificate is the lookup key, so a nil signer makes the operation impossible; the function rejects it up front with this error rather than panicking later on a nil dereference.
Source
Thrown at upup/pkg/fi/cloudup/azure/attest.go:336
return nil, fmt.Errorf("parsing attested document expiration: %w", err)
}
if expiresOn.Before(createdOn) {
return nil, fmt.Errorf("attested document expiresOn %s is before createdOn %s", data.TimeStamp.ExpiresOn, data.TimeStamp.CreatedOn)
}
if expiresOn.Before(now.Add(-attestedDocumentMaxClockSkew)) {
return nil, fmt.Errorf("attested document expired at %s", data.TimeStamp.ExpiresOn)
}
klog.V(4).Infof("Attested document not expired (expiresOn=%s)", expiresOn.Format(time.RFC3339))
}
return &data, nil
}
// intermediateCertPoolWithCaches performs a cached lookup against the supplied positive and
// negative TTL caches, invoking fetch on a miss. Tests inject their own stores and fetchers.
func intermediateCertPoolWithCaches(signer *x509.Certificate, fetch func(*x509.Certificate) (*x509.CertPool, error), positive, negative expirationcache.Store) (*x509.CertPool, error) {
if signer == nil {
return nil, fmt.Errorf("signer certificate is required")
}
keyStr := intermediateCacheKeyForSigner(signer)
// Positive cache wins over negative: a successful later fetch overwrites any stale negative entry,
// which expires on its own shorter TTL.
if obj, ok, _ := positive.GetByKey(keyStr); ok {
klog.V(4).Infof("Intermediate certificate cache hit (positive) for signer issuer %q", signer.Issuer)
return obj.(*intermediateCertCacheEntry).pool, nil
}
if _, ok, _ := negative.GetByKey(keyStr); ok {
klog.V(4).Infof("Intermediate certificate cache hit (negative) for signer issuer %q", signer.Issuer)
return nil, fmt.Errorf("intermediate certificate fetch recently failed for signer issuer %q (cached)", signer.Issuer)
}
klog.V(2).Infof("Intermediate certificate cache miss for signer issuer %q", signer.Issuer)
pool, fetchErr := fetch(signer)
entry := &intermediateCertCacheEntry{key: keyStr, pool: pool}View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the caller extracts and validates the signer certificate before calling intermediateCertPoolForSigner
- Return and handle errors from certificate parsing steps so a nil certificate never reaches the cache lookup
- Add an assertion or guard in the calling code path to fail fast with a clearer message
Example fix
// before
pool, err := intermediateCertPoolForSigner(signerFromChain) // signer may be nil
// after
if signerFromChain == nil {
return nil, fmt.Errorf("no signer certificate available to build intermediate pool")
}
pool, err := intermediateCertPoolForSigner(signerFromChain) Defensive patterns
Strategy: validation
Validate before calling
if signer == nil {
return nil, fmt.Errorf("signer certificate missing before intermediate pool lookup")
}
pool, err := intermediateCertPoolForSigner(signer) Type guard
func hasSigner(c *x509.Certificate) bool { return c != nil && len(c.Raw) > 0 } Try / catch
pool, err := intermediateCertPoolForSigner(signer)
if err != nil {
if strings.Contains(err.Error(), "signer certificate is required") {
return nil, fmt.Errorf("programming error: nil signer passed to cache lookup: %w", err)
}
return nil, err
} Prevention
- Check errors from every certificate-parsing call before using the result
- Never propagate a nil certificate as a cache key
- Add unit assertions that chain extraction always yields a non-nil signer on success
When it happens
Trigger: Calling intermediateCertPoolWithCaches (via intermediateCertPoolForSigner) with signer == nil, typically when an upstream parsing step failed silently or a nil certificate was propagated into the cache lookup path.
Common situations: A caller that skipped error handling when extracting the signer certificate from a chain; tests accidentally passing nil; refactoring that removed an earlier nil check.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- no fetched intermediate certificates matched signer issuer %
- intermediate certificate from %s exceeds %d bytes
- parsing intermediate certificate from %s: %w
- decoding pem public key
- parsing key: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8ddc37182bc6db4e.
Report an issue: GitHub.