{"record":{"id":"ac9b671e4d245756","repo":"grpc/grpc-go","slug":"crl-only-contains-some-certificate-types","errorCode":null,"errorMessage":"CRL only contains some certificate types","messagePattern":"CRL only contains some certificate types","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"security/advancedtls/crl.go","lineNumber":345,"sourceCode":"\t\tcase oidAuthorityKeyIdentifier.Equal(ext.Id):\n\t\t\tvar a authKeyID\n\t\t\tif rest, err := asn1.Unmarshal(ext.Value, &a); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"asn1.Unmarshal failed: %v\", err)\n\t\t\t} else if len(rest) != 0 {\n\t\t\t\treturn nil, errors.New(\"trailing data after AKID extension\")\n\t\t\t}\n\t\t\tcertList.authorityKeyID = a.ID\n\n\t\tcase oidIssuingDistributionPoint.Equal(ext.Id):\n\t\t\tvar dp issuingDistributionPoint\n\t\t\tif rest, err := asn1.Unmarshal(ext.Value, &dp); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"asn1.Unmarshal failed: %v\", err)\n\t\t\t} else if len(rest) != 0 {\n\t\t\t\treturn nil, errors.New(\"trailing data after IssuingDistributionPoint extension\")\n\t\t\t}\n\n\t\t\tif dp.OnlyContainsUserCerts || dp.OnlyContainsCACerts || dp.OnlyContainsAttributeCerts {\n\t\t\t\treturn nil, errors.New(\"CRL only contains some certificate types\")\n\t\t\t}\n\t\t\tif dp.IndirectCRL {\n\t\t\t\treturn nil, errors.New(\"indirect CRLs unsupported\")\n\t\t\t}\n\t\t\tif dp.OnlySomeReasons.BitLength != 0 {\n\t\t\t\treturn nil, errors.New(\"onlySomeReasons unsupported\")\n\t\t\t}\n\n\t\tcase ext.Critical:\n\t\t\treturn nil, fmt.Errorf(\"unsupported critical extension: %v\", ext.Id)\n\t\t}\n\t}\n\n\tif len(certList.authorityKeyID) == 0 {\n\t\treturn nil, errors.New(\"authority key identifier extension missing\")\n\t}\n\treturn certList, nil\n}","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/security/advancedtls/crl.go#L327-L363","documentation":"Returned by parseCRLExtensions when the IssuingDistributionPoint extension indicates the CRL only covers a subset of cert types: onlyContainsUserCerts, onlyContainsCACerts, or onlyContainsAttributeCerts is set. grpc-go's CRL handling does not implement type-scoped revocation lists; such a partial CRL could give wrong answers, so it is rejected.","triggerScenarios":"The CRL's IDP extension has one of OnlyContainsUserCerts / OnlyContainsCACerts / OnlyContainsAttributeCerts = true. Triggered during CRL parsing in the advancedtls package when loading a type-restricted CRL.","commonSituations":"A CA publishes separate CRLs for end-entity and CA certs (a common PKI practice). The operator pointed grpc-go's CRL provider at one of these scoped CRLs instead of a complete CRL. Enterprise PKI that uses attribute-cert CRLs.","solutions":["Use a complete (unscoped) CRL from the CA, i.e. one whose IDP extension does not restrict cert types.","If only scoped CRLs are available, request the CA publish a full CRL or use OCSP for the scoped subset.","Confirm the URL/file the CRL provider points at is the base CRL, not a partitioned/shard CRL."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Reject scoped CRLs before handing them to advancedtls.\nfunc isFullCRL(crlDER []byte) (bool, error) {\n    l, err := x509.ParseRevocationList(crlDER)\n    if err != nil { return false, err }\n    for _, ext := range l.Extensions {\n        if ext.Id.Equal(oidIssuingDistributionPoint) {\n            var dp issuingDistributionPoint\n            if _, err := asn1.Unmarshal(ext.Value, &dp); err != nil { return false, err }\n            if dp.OnlyContainsUserCerts || dp.OnlyContainsCACerts || dp.OnlyContainsAttributeCerts {\n                return false, nil\n            }\n        }\n    }\n    return true, nil\n}","typeGuard":null,"tryCatchPattern":"When loading CRLs, skip type-scoped ones with a logged warning; keep the previous full CRL active. Do not fall back to no-CRL silently.","preventionTips":["Document which CRL distribution points serve full vs scoped CRLs.","Add a pre-install check rejecting scoped CRLs for grpc-go workloads.","Coordinate with PKI team to publish at least one base CRL per CA."],"tags":["tls","crl","advancedtls","pkix","issuing-distribution-point"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}