{"record":{"id":"9627a77dec25bf7b","repo":"oven-sh/bun","slug":"crl-has-expired","errorCode":"CRL_HAS_EXPIRED","errorMessage":"CRL_HAS_EXPIRED","messagePattern":"CRL_HAS_EXPIRED","errorType":"error_code","errorClass":"CertError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":145,"sourceCode":"    #[error(\"UNABLE_TO_GET_CRL\")]\n    UNABLE_TO_GET_CRL,\n    #[error(\"UNABLE_TO_DECRYPT_CERT_SIGNATURE\")]\n    UNABLE_TO_DECRYPT_CERT_SIGNATURE,\n    #[error(\"UNABLE_TO_DECRYPT_CRL_SIGNATURE\")]\n    UNABLE_TO_DECRYPT_CRL_SIGNATURE,\n    #[error(\"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY\")]\n    UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY,\n    #[error(\"CERT_SIGNATURE_FAILURE\")]\n    CERT_SIGNATURE_FAILURE,\n    #[error(\"CRL_SIGNATURE_FAILURE\")]\n    CRL_SIGNATURE_FAILURE,\n    #[error(\"CERT_NOT_YET_VALID\")]\n    CERT_NOT_YET_VALID,\n    #[error(\"CERT_HAS_EXPIRED\")]\n    CERT_HAS_EXPIRED,\n    #[error(\"CRL_NOT_YET_VALID\")]\n    CRL_NOT_YET_VALID,\n    #[error(\"CRL_HAS_EXPIRED\")]\n    CRL_HAS_EXPIRED,\n    #[error(\"ERROR_IN_CERT_NOT_BEFORE_FIELD\")]\n    ERROR_IN_CERT_NOT_BEFORE_FIELD,\n    #[error(\"ERROR_IN_CERT_NOT_AFTER_FIELD\")]\n    ERROR_IN_CERT_NOT_AFTER_FIELD,\n    #[error(\"ERROR_IN_CRL_LAST_UPDATE_FIELD\")]\n    ERROR_IN_CRL_LAST_UPDATE_FIELD,\n    #[error(\"ERROR_IN_CRL_NEXT_UPDATE_FIELD\")]\n    ERROR_IN_CRL_NEXT_UPDATE_FIELD,\n    #[error(\"OUT_OF_MEM\")]\n    OUT_OF_MEM,\n    #[error(\"DEPTH_ZERO_SELF_SIGNED_CERT\")]\n    DEPTH_ZERO_SELF_SIGNED_CERT,\n    #[error(\"SELF_SIGNED_CERT_IN_CHAIN\")]\n    SELF_SIGNED_CERT_IN_CHAIN,\n    #[error(\"UNABLE_TO_GET_ISSUER_CERT_LOCALLY\")]\n    UNABLE_TO_GET_ISSUER_CERT_LOCALLY,\n    #[error(\"UNABLE_TO_VERIFY_LEAF_SIGNATURE\")]","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L127-L163","documentation":"X509 verify result 12 (X509_V_ERR_CRL_HAS_EXPIRED): the CRL is past its nextUpdate, so revocation information is stale and cannot be trusted for a definitive answer. Mapped via get_cert_error_from_no (src/http/lib.rs:1531) to CertError::CRL_HAS_EXPIRED, message \"CRL has expired\" (FetchTasklet.rs:1406).","triggerScenarios":"TLS handshake with CRL checking active where the published CRL's nextUpdate has passed and the CA has not issued a newer one.","commonSituations":"Internal CAs whose automated CRL generation job died, long-lived appliances publishing CRLs with short validity, decommissioned PKIs whose CRLs lapsed while certs are still in use.","solutions":["Have the CA operations team regenerate and republish the CRL (fix the cron/job that signs CRLs)","Until then, drop the hard CRL requirement client-side or switch the host to OCSP","Extend nextUpdate periods on the CA's CRL profile if publication cadence is slow","Migrate certs off the lapsed PKI if it is no longer maintained"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isCertErrorCode(e: unknown, code = \"CRL_HAS_EXPIRED\"): e is Error & { code: string } {\n  return e instanceof Error && (e as any).code === code;\n}","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (isCertErrorCode(e, \"CRL_HAS_EXPIRED\")) {\n    throw new Error(\"Revocation data stale (CRL expired) — PKI ops must republish\");\n  }\n  throw e;\n}","preventionTips":["Automate CRL republication with nextUpdate well beyond the signing cadence","Alert on CRL nextUpdate approaching on the distribution servers","Don't hard-require CRLs client-side unless the PKI is demonstrably maintained"],"tags":["tls","certificates","crl","revocation","fetch"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}