grpc/grpc-go · error
authority key identifier extension missing
Error message
authority key identifier extension missing
What it means
Returned by parseCRLExtensions after iterating all extensions of the CRL: certList.authorityKeyID is still empty. RFC 5280 5.2.1 mandates the AuthorityKeyIdentifier extension in conforming CRLs; grpc-go relies on it to correlate the CRL to the issuing certificate's SubjectKeyId during signature verification. Without it, the CRL cannot be validated and is rejected.
Solutions
- Regenerate the CRL with the AuthorityKeyIdentifier extension included (default for conformant CA tooling).
- If using OpenSSL, ensure the CA cert has a subjectKeyIdentifier so the generated CRL includes AKID.
- Switch CA software or request the operator include the AKID extension on the CRL.
Defensive patterns
Strategy: validation
Validate before calling
// Require the AuthorityKeyIdentifier extension on any CRL we install.
func crlHasAKID(crlDER []byte) (bool, error) {
l, err := x509.ParseRevocationList(crlDER)
if err != nil { return false, err }
for _, ext := range l.Extensions {
if ext.Id.Equal(oidAuthorityKeyIdentifier) { return true, nil }
}
return false, nil
} Try / catch
On parse failure citing missing AKID, retain the previous CRL and alert. Coordinate with the CA to reissue a conformant CRL.
Prevention
- Ensure issuing CA certs carry a subjectKeyIdentifier so generated CRLs include AKID.
- Validate CRLs with openssl -text in CI to spot missing extensions.
- Maintain a known-good CRL cache so missing-AKID refreshes do not break revocation.
When it happens
Trigger: A CRL was parsed successfully but contained no AuthorityKeyIdentifier extension (oid 2.5.29.35). Triggered when loading a CRL via the advancedtls CRL provider.
Common situations: Non-conformant CA that omits AKID from CRLs (older OpenSSL versions, lightweight CAs, test CAs). CRL generated by minimal tooling that skips optional-but-expected extensions. Stripped-down CRL used in a constrained environment.
Related errors
- CRL only contains some certificate types
- extractCRLIssuer: invalid ASN.1 encoding
- indirect CRLs unsupported
- no DN found in certificate issuer
- onlySomeReasons unsupported
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/c1ad59e448ac4dfb.
Report an issue: GitHub.
Appendix: source
Thrown at security/advancedtls/crl.go:360
}
if dp.OnlyContainsUserCerts || dp.OnlyContainsCACerts || dp.OnlyContainsAttributeCerts {
return nil, errors.New("CRL only contains some certificate types")
}
if dp.IndirectCRL {
return nil, errors.New("indirect CRLs unsupported")
}
if dp.OnlySomeReasons.BitLength != 0 {
return nil, errors.New("onlySomeReasons unsupported")
}
case ext.Critical:
return nil, fmt.Errorf("unsupported critical extension: %v", ext.Id)
}
}
if len(certList.authorityKeyID) == 0 {
return nil, errors.New("authority key identifier extension missing")
}
return certList, nil
}
func verifyCRL(crl *CRL, chain []*x509.Certificate) error {
// RFC5280, 6.3.3 (f) Obtain and validate the certification path for the issuer of the complete CRL
// We intentionally limit our CRLs to be signed with the same certificate path as the certificate
// so we can use the chain from the connection.
for _, c := range chain {
// Use the key where the subject and KIDs match.
// This departs from RFC4158, 3.5.12 which states that KIDs
// cannot eliminate certificates, but RFC5280, 5.2.1 states that
// "Conforming CRL issuers MUST use the key identifier method, and MUST
// include this extension in all CRLs issued."
// So, this is much simpler than RFC4158 and should be compatible.
if bytes.Equal(c.SubjectKeyId, crl.authorityKeyID) && bytes.Equal(c.RawSubject, crl.rawIssuer) {
// RFC5280, 6.3.3 (f) Key usage and cRLSign bit.View on GitHub (pinned to 0c51461d27)