{"record":{"id":"12e41be42f940730","repo":"oven-sh/bun","slug":"unhandled-critical-crl-extension","errorCode":"UNHANDLED_CRITICAL_CRL_EXTENSION","errorMessage":"UNHANDLED_CRITICAL_CRL_EXTENSION","messagePattern":"UNHANDLED_CRITICAL_CRL_EXTENSION","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":193,"sourceCode":"    #[error(\"CERT_UNTRUSTED\")]\n    CERT_UNTRUSTED,\n    #[error(\"CERT_REJECTED\")]\n    CERT_REJECTED,\n    #[error(\"SUBJECT_ISSUER_MISMATCH\")]\n    SUBJECT_ISSUER_MISMATCH,\n    #[error(\"AKID_SKID_MISMATCH\")]\n    AKID_SKID_MISMATCH,\n    #[error(\"AKID_ISSUER_SERIAL_MISMATCH\")]\n    AKID_ISSUER_SERIAL_MISMATCH,\n    #[error(\"KEYUSAGE_NO_CERTSIGN\")]\n    KEYUSAGE_NO_CERTSIGN,\n    #[error(\"UNABLE_TO_GET_CRL_ISSUER\")]\n    UNABLE_TO_GET_CRL_ISSUER,\n    #[error(\"UNHANDLED_CRITICAL_EXTENSION\")]\n    UNHANDLED_CRITICAL_EXTENSION,\n    #[error(\"KEYUSAGE_NO_CRL_SIGN\")]\n    KEYUSAGE_NO_CRL_SIGN,\n    #[error(\"UNHANDLED_CRITICAL_CRL_EXTENSION\")]\n    UNHANDLED_CRITICAL_CRL_EXTENSION,\n    #[error(\"INVALID_NON_CA\")]\n    INVALID_NON_CA,\n    #[error(\"PROXY_PATH_LENGTH_EXCEEDED\")]\n    PROXY_PATH_LENGTH_EXCEEDED,\n    #[error(\"KEYUSAGE_NO_DIGITAL_SIGNATURE\")]\n    KEYUSAGE_NO_DIGITAL_SIGNATURE,\n    #[error(\"PROXY_CERTIFICATES_NOT_ALLOWED\")]\n    PROXY_CERTIFICATES_NOT_ALLOWED,\n    #[error(\"INVALID_EXTENSION\")]\n    INVALID_EXTENSION,\n    #[error(\"INVALID_POLICY_EXTENSION\")]\n    INVALID_POLICY_EXTENSION,\n    #[error(\"NO_EXPLICIT_POLICY\")]\n    NO_EXPLICIT_POLICY,\n    #[error(\"DIFFERENT_CRL_SCOPE\")]\n    DIFFERENT_CRL_SCOPE,\n    #[error(\"UNSUPPORTED_EXTENSION_FEATURE\")]","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L175-L211","documentation":"CertError::UNHANDLED_CRITICAL_CRL_EXTENSION maps BoringSSL X509 verify code 36 (X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION) via get_cert_error_from_no() in src/http/lib.rs:1555. A CRL used during revocation checking contains a critical extension the verifier does not support (e.g., certain Issuing Distribution Point or freshestCRL configurations), so the CRL is rejected. JS error.code is UNHANDLED_CRITICAL_CRL_EXTENSION with message 'unhandled critical CRL extension' (FetchTasklet.rs:1493).","triggerScenarios":"CRL validation runs against a CRL whose Issuing Distribution Point or other CRL extension is marked critical with parameters BoringSSL refuses (indirect CRL flags, onlyContainsAttributeCerts, unsupported scope).","commonSituations":"Enterprise CA products (ADCS, EJBCA) emitting IDP-critical CRLs for scoped/indirect revocation, split CRL scopes where the fetched CRL does not cover the cert being checked, private PKI experimenting with CRL scopes.","solutions":["Inspect the CRL: openssl crl -in crl.pem -noout -text and review extensions marked critical","Reissue the CRL without the problematic critical flag or with a scope covering the certificate","Ensure the client fetches the CRL whose scope matches (full CRL, not a partitioned one)","If revocation is not a hard requirement on this path, remove CRL material from the verification setup"],"exampleFix":"# before: scoped CRL with critical IDP that excludes this cert\nopenssl crl -in partition-1.crl.pem -noout -text | grep -A3 'Issuing Distribution Point'\n# after: publish a full-scope, non-critical-IDP CRL\nopenssl ca -gencrl -keyfile ca-key.pem -cert ca.pem -out full.crl.pem\n# client uses full.crl.pem","handlingStrategy":"try-catch","validationCode":"import { execSync } from \"node:child_process\";\nconst text = execSync(\"openssl crl -in crl.pem -noout -text\").toString();\nif (/Issuing Distribution Point:[\\s\\S]*?critical|Unknown Extension[\\s\\S]*?critical/i.test(text)) {\n  throw new Error(\"CRL has critical extensions the verifier may not support\");\n}","typeGuard":"function isUnhandledCriticalCrlExt(e: unknown): e is Error & { code: \"UNHANDLED_CRITICAL_CRL_EXTENSION\" } {\n  return e instanceof Error && (e as any).code === \"UNHANDLED_CRITICAL_CRL_EXTENSION\";\n}","tryCatchPattern":"try { await fetch(url); } catch (e) { if (isUnhandledCriticalCrlExt(e)) { switchToOcspOrFullCrl(new URL(url).host); throw e; } throw e; }","preventionTips":["Prefer full-scope CRLs over partitioned/scoped CRLs","Do not mark IDP or exotic CRL extensions critical","Use OCSP/AIA endpoints instead of direct CRL files when possible"],"tags":["tls","crl","revocation","pki","x509-extensions"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}