{"record":{"id":"bf2de4de755a1766","repo":"grpc/grpc-go","slug":"indirect-crls-unsupported","errorCode":null,"errorMessage":"indirect CRLs unsupported","messagePattern":"indirect CRLs unsupported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"security/advancedtls/crl.go","lineNumber":348,"sourceCode":"\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}\n\nfunc verifyCRL(crl *CRL, chain []*x509.Certificate) error {\n\t// RFC5280, 6.3.3 (f) Obtain and validate the certification path for the issuer of the complete CRL","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/security/advancedtls/crl.go#L330-L366","documentation":"Returned by parseCRLExtensions when the IssuingDistributionPoint extension has indirectCRL=true. An indirect CRL is signed by an authority other than the cert issuer and uses per-entry Certificate Issuer extensions; grpc-go's CRL support is intentionally limited to direct CRLs signed by the same chain as the cert, so indirect CRLs are rejected.","triggerScenarios":"The CRL's IDP extension sets IndirectCRL=true (or the CRL otherwise carries a different issuer than the certificate's issuer). Triggered during CRL parsing in advancedtls.","commonSituations":"A third-party CA delegates CRL signing to a dedicated CRL issuer (common in large PKIs). The CRL distribution point serves an indirect CRL by default. Operator reused a CRL intended for a different trust chain.","solutions":["Switch to a direct CRL signed by the same CA that issued the certificate (matching subject/issuer DN and AKID).","If only indirect CRLs exist for the chain, disable CRL revocation and rely on OCSP.","Verify the CRL distributionPoint URI in the certificate points to the direct CRL."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Detect indirect CRLs before installing them.\nfunc isDirectCRL(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.IndirectCRL { return false, nil }\n        }\n    }\n    return true, nil\n}","typeGuard":null,"tryCatchPattern":"On 'indirect CRLs unsupported', log and continue with the previous (direct) CRL. Surface the issue so PKI can provide a direct CRL.","preventionTips":["Confirm CRL issuer DN matches the certificate's issuer DN before installing.","Avoid pointing grpc-go's CRL provider at delegated-CRL-issuer distribution points.","Run a CI gate that rejects indirect CRLs for grpc-go deployments."],"tags":["tls","crl","advancedtls","pkix","indirect-crl"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}