{"record":{"id":"f3bd6844d8ff802d","repo":"oven-sh/bun","slug":"crl-path-validation-error","errorCode":"CRL_PATH_VALIDATION_ERROR","errorMessage":"CRL_PATH_VALIDATION_ERROR","messagePattern":"CRL_PATH_VALIDATION_ERROR","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":229,"sourceCode":"    #[error(\"UNSUPPORTED_EXTENSION_FEATURE\")]\n    UNSUPPORTED_EXTENSION_FEATURE,\n    #[error(\"UNNESTED_RESOURCE\")]\n    UNNESTED_RESOURCE,\n    #[error(\"PERMITTED_VIOLATION\")]\n    PERMITTED_VIOLATION,\n    #[error(\"EXCLUDED_VIOLATION\")]\n    EXCLUDED_VIOLATION,\n    #[error(\"SUBTREE_MINMAX\")]\n    SUBTREE_MINMAX,\n    #[error(\"APPLICATION_VERIFICATION\")]\n    APPLICATION_VERIFICATION,\n    #[error(\"UNSUPPORTED_CONSTRAINT_TYPE\")]\n    UNSUPPORTED_CONSTRAINT_TYPE,\n    #[error(\"UNSUPPORTED_CONSTRAINT_SYNTAX\")]\n    UNSUPPORTED_CONSTRAINT_SYNTAX,\n    #[error(\"UNSUPPORTED_NAME_SYNTAX\")]\n    UNSUPPORTED_NAME_SYNTAX,\n    #[error(\"CRL_PATH_VALIDATION_ERROR\")]\n    CRL_PATH_VALIDATION_ERROR,\n    #[error(\"SUITE_B_INVALID_VERSION\")]\n    SUITE_B_INVALID_VERSION,\n    #[error(\"SUITE_B_INVALID_ALGORITHM\")]\n    SUITE_B_INVALID_ALGORITHM,\n    #[error(\"SUITE_B_INVALID_CURVE\")]\n    SUITE_B_INVALID_CURVE,\n    #[error(\"SUITE_B_INVALID_SIGNATURE_ALGORITHM\")]\n    SUITE_B_INVALID_SIGNATURE_ALGORITHM,\n    #[error(\"SUITE_B_LOS_NOT_ALLOWED\")]\n    SUITE_B_LOS_NOT_ALLOWED,\n    #[error(\"SUITE_B_CANNOT_SIGN_P_384_WITH_P_256\")]\n    SUITE_B_CANNOT_SIGN_P_384_WITH_P_256,\n    #[error(\"HOSTNAME_MISMATCH\")]\n    HOSTNAME_MISMATCH,\n    #[error(\"EMAIL_MISMATCH\")]\n    EMAIL_MISMATCH,\n    #[error(\"IP_ADDRESS_MISMATCH\")]","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L211-L247","documentation":"CertError::CRL_PATH_VALIDATION_ERROR maps BoringSSL X509_V_ERR_CRL_PATH_VALIDATION_ERROR (verify code 54). With CRL checking enabled, the certificate chain of the CRL issuer itself failed validation - the CRL's signing path is untrusted, expired, or violates constraints. Message: \"CRL path validation error\".","triggerScenarios":"X509_V_FLAG_CRL_CHECK(_ALL) verification where the CRL presented/fetched cannot be chained to the trust store: CRL signer cert expired, missing from the store, or its own chain violates basicConstraints/keyUsage.","commonSituations":"CRL signer certificates that expire quietly (common - they are short-lived); containers/hosts missing the CA bundle that contains the indirect CRL issuer; PKIs rotating CRL signing keys without republishing signer certs.","solutions":["Validate the CRL chain directly: openssl crl -in crl.pem -noout -issuer and openssl verify -crl_check -CAfile ca.pem leaf.pem","Renew/reissue the CRL signer certificate and republish the CRL","Ensure the verifier's trust store contains the CRL issuer's chain","If revocation is via OCSP only, disable CRL fetching on the verifier to avoid the dead path"],"exampleFix":"# before: expired CRL signer silently breaks every handshake\nopenssl ca -gencrl -out stale.crl   # signer cert already expired\n\n# after: reissue signer, then regenerate + republish CRL\nopenssl x509 -req -in crl-signer.csr -CA ca.pem -days 365 -extfile crl_signer.ext\nopenssl ca -gencrl -out fresh.crl","handlingStrategy":"try-catch","validationCode":"// Pre-check the CRL path is verifiable whenever CRL checking is enabled\nimport { execFileSync } from \"node:child_process\";\nexport function crlPathVerifies(certPem, crlPem, caPem) {\n  execFileSync(\"openssl\", [\"verify\", \"-crl_check\", \"-CRLfile\", crlPem, \"-CAfile\", caPem, certPem], { stdio: \"pipe\" });\n  return true; // throws with the CRL-path failure otherwise\n}","typeGuard":"export function isCrlPathValidationError(e): e is Error & { code: \"CRL_PATH_VALIDATION_ERROR\" } {\n  return e instanceof Error && (e as any).code === \"CRL_PATH_VALIDATION_ERROR\";\n}","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (e?.code === \"CRL_PATH_VALIDATION_ERROR\") {\n    // the CRL issuer's own chain failed - renew CRL signer certs / fix the store\n    pagePkiOnCall(\"crl-path\", url);\n  } else throw e;\n}","preventionTips":["Monitor CRL signer certificate expiry as aggressively as TLS cert expiry - they fail quietly","Include the indirect CRL issuer chain in every verifier's trust store","Schedule openssl verify -crl_check probes against your own endpoints to catch CRL path rot early"],"tags":["tls","x509","crl","revocation","pki","fetch","security"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}