{"record":{"id":"29ccf391a2900627","repo":"oven-sh/bun","slug":"cert-rejected","errorCode":"CERT_REJECTED","errorMessage":"CERT_REJECTED","messagePattern":"CERT_REJECTED","errorType":"error_code","errorClass":"CertError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":177,"sourceCode":"    #[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\")]\n    UNABLE_TO_VERIFY_LEAF_SIGNATURE,\n    #[error(\"CERT_CHAIN_TOO_LONG\")]\n    CERT_CHAIN_TOO_LONG,\n    #[error(\"CERT_REVOKED\")]\n    CERT_REVOKED,\n    #[error(\"INVALID_CA\")]\n    INVALID_CA,\n    #[error(\"PATH_LENGTH_EXCEEDED\")]\n    PATH_LENGTH_EXCEEDED,\n    #[error(\"INVALID_PURPOSE\")]\n    INVALID_PURPOSE,\n    #[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\")]","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L159-L195","documentation":"CertError::CERT_REJECTED maps BoringSSL X509 verify code 28 (X509_V_ERR_CERT_REJECTED) via get_cert_error_from_no() in src/http/lib.rs:1547. The root CA itself is trusted in the store but is not accepted for the requested purpose (TLS), so the chain is rejected at the anchor check. JS error.code is CERT_REJECTED with message 'certificate rejected' (FetchTasklet.rs:1463).","triggerScenarios":"A root whose trust-store entry limits it to code signing or S/MIME is used to terminate a TLS server chain; purpose-specific trust (e.g., emailProtection-only root) during X509 purpose checking of an SSL connection.","commonSituations":"Repurposing a code-signing root for internal HTTPS, CA bundles installed for package signing (e.g., some artifact-signing roots) mistakenly serving TLS, exotic private CAs created without any TLS-compatible purpose.","solutions":["Identify the anchor: openssl s_client -connect host:443 -showcerts — the last self-signed cert","Replace the TLS chain with one rooted in a CA intended for SSL/TLS server auth","If it is your own root, reissue the root with keyUsage=keyCertSign,cRLSign and no EKU restriction that excludes serverAuth","Add the root explicitly per-connection via tls: { ca } so purpose rules come from the cert, not a restricted store entry"],"exampleFix":"# before: chain terminates in a code-signing root (rejected for TLS)\nopenssl verify -purpose sslserver -CAfile codesign-root.pem leaf.pem\n# after: reissue under a TLS-capable root\nopenssl verify -purpose sslserver -CAfile tls-root.pem leaf.pem  # must print OK","handlingStrategy":"try-catch","validationCode":"import { execSync } from \"node:child_process\";\nconst ok = execSync(`openssl verify -purpose sslserver -CAfile anchor.pem leaf.pem`).toString();\nif (!ok.includes(\": OK\")) throw new Error(\"anchor rejected for TLS server purpose\");","typeGuard":"function isCertRejected(e: unknown): e is Error & { code: \"CERT_REJECTED\" } {\n  return e instanceof Error && (e as any).code === \"CERT_REJECTED\";\n}","tryCatchPattern":"try { await fetch(url); } catch (e) { if (isCertRejected(e)) { escalateToSecurityTeam(`anchor not permitted for TLS: ${url}`); throw e; } throw e; }","preventionTips":["Use TLS-purpose roots for TLS; keep signing roots in separate bundles","Check anchors with openssl verify -purpose sslserver before deployment","Maintain a registry of which root serves which purpose"],"tags":["tls","certificate","trust-store","purpose","fetch"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}