oven-sh/bun · error · TypeError

UNHANDLED_CRITICAL_CRL_EXTENSION

UNHANDLED_CRITICAL_CRL_EXTENSION

Error message

UNHANDLED_CRITICAL_CRL_EXTENSION

What it means

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).

Source

Thrown at src/http/error.rs:193

    #[error("CERT_UNTRUSTED")]
    CERT_UNTRUSTED,
    #[error("CERT_REJECTED")]
    CERT_REJECTED,
    #[error("SUBJECT_ISSUER_MISMATCH")]
    SUBJECT_ISSUER_MISMATCH,
    #[error("AKID_SKID_MISMATCH")]
    AKID_SKID_MISMATCH,
    #[error("AKID_ISSUER_SERIAL_MISMATCH")]
    AKID_ISSUER_SERIAL_MISMATCH,
    #[error("KEYUSAGE_NO_CERTSIGN")]
    KEYUSAGE_NO_CERTSIGN,
    #[error("UNABLE_TO_GET_CRL_ISSUER")]
    UNABLE_TO_GET_CRL_ISSUER,
    #[error("UNHANDLED_CRITICAL_EXTENSION")]
    UNHANDLED_CRITICAL_EXTENSION,
    #[error("KEYUSAGE_NO_CRL_SIGN")]
    KEYUSAGE_NO_CRL_SIGN,
    #[error("UNHANDLED_CRITICAL_CRL_EXTENSION")]
    UNHANDLED_CRITICAL_CRL_EXTENSION,
    #[error("INVALID_NON_CA")]
    INVALID_NON_CA,
    #[error("PROXY_PATH_LENGTH_EXCEEDED")]
    PROXY_PATH_LENGTH_EXCEEDED,
    #[error("KEYUSAGE_NO_DIGITAL_SIGNATURE")]
    KEYUSAGE_NO_DIGITAL_SIGNATURE,
    #[error("PROXY_CERTIFICATES_NOT_ALLOWED")]
    PROXY_CERTIFICATES_NOT_ALLOWED,
    #[error("INVALID_EXTENSION")]
    INVALID_EXTENSION,
    #[error("INVALID_POLICY_EXTENSION")]
    INVALID_POLICY_EXTENSION,
    #[error("NO_EXPLICIT_POLICY")]
    NO_EXPLICIT_POLICY,
    #[error("DIFFERENT_CRL_SCOPE")]
    DIFFERENT_CRL_SCOPE,
    #[error("UNSUPPORTED_EXTENSION_FEATURE")]

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Inspect the CRL: openssl crl -in crl.pem -noout -text and review extensions marked critical
  2. Reissue the CRL without the problematic critical flag or with a scope covering the certificate
  3. Ensure the client fetches the CRL whose scope matches (full CRL, not a partitioned one)
  4. If revocation is not a hard requirement on this path, remove CRL material from the verification setup

Example fix

# before: scoped CRL with critical IDP that excludes this cert
openssl crl -in partition-1.crl.pem -noout -text | grep -A3 'Issuing Distribution Point'
# after: publish a full-scope, non-critical-IDP CRL
openssl ca -gencrl -keyfile ca-key.pem -cert ca.pem -out full.crl.pem
# client uses full.crl.pem
Defensive patterns

Strategy: try-catch

Validate before calling

import { execSync } from "node:child_process";
const text = execSync("openssl crl -in crl.pem -noout -text").toString();
if (/Issuing Distribution Point:[\s\S]*?critical|Unknown Extension[\s\S]*?critical/i.test(text)) {
  throw new Error("CRL has critical extensions the verifier may not support");
}

Type guard

function isUnhandledCriticalCrlExt(e: unknown): e is Error & { code: "UNHANDLED_CRITICAL_CRL_EXTENSION" } {
  return e instanceof Error && (e as any).code === "UNHANDLED_CRITICAL_CRL_EXTENSION";
}

Try / catch

try { await fetch(url); } catch (e) { if (isUnhandledCriticalCrlExt(e)) { switchToOcspOrFullCrl(new URL(url).host); throw e; } throw e; }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/12e41be42f940730. Report an issue: GitHub.