{"record":{"id":"c9b914ba02f97235","repo":"oven-sh/bun","slug":"unhandled-critical-extension","errorCode":"UNHANDLED_CRITICAL_EXTENSION","errorMessage":"UNHANDLED_CRITICAL_EXTENSION","messagePattern":"UNHANDLED_CRITICAL_EXTENSION","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":189,"sourceCode":"    #[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\")]\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\")]","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L171-L207","documentation":"CertError::UNHANDLED_CRITICAL_EXTENSION maps BoringSSL X509 verify code 34 (X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) via get_cert_error_from_no() in src/http/lib.rs:1553. The certificate contains an extension marked critical that the verifier does not recognize or process; per RFC 5280 the chain must then be rejected. JS error.code is UNHANDLED_CRITICAL_EXTENSION with message 'unhandled critical extension' (FetchTasklet.rs:1484).","triggerScenarios":"Server certificate (or an intermediate) carries a private-OID or uncommon extension flagged critical — e.g., Certificate Transparency poison, vendor-specific policy OIDs, legacy Microsoft templates — none of which BoringSSL handles during fetch()'s verification.","commonSituations":"Certs issued by unusual/legacy CAs or enterprise Microsoft ADCS templates that mark proprietary OIDs critical, pre-certificate (CT poison) artifacts escaping into production chains, certs produced by custom openssl configs with addext and critical set.","solutions":["Find the offending extension: openssl x509 -in cert.pem -noout -text and look for 'critical' next to nonstandard OIDs","Have the cert reissued with that extension non-critical (or removed) — most CAs will do this on request","If the extension is on an intermediate, switch to a chain variant without it (often an alternate cross-signed path exists)","Do not disable verification globally; if forced for an internal endpoint, scope it: tls: { rejectUnauthorized: false } on that one request, test only"],"exampleFix":"# before\n[ext]\n1.3.6.1.4.1.99999.1=critical,DER:...   # private OID marked critical\n# after\n[ext]\n1.3.6.1.4.1.99999.1=DER:...            # drop critical flag\nopenssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -extfile ext.cnf -out server.pem","handlingStrategy":"try-catch","validationCode":"import { X509Certificate } from \"node:crypto\";\nconst cert = new X509Certificate(await Bun.file(\"server.pem\").text());\nconst text = await Bun.$`openssl x509 -in server.pem -noout -text`.text();\nconst unknownCritical = [...text.matchAll(/(\\d+\\.\\d+(?:\\.\\d+)+):\\s*critical/g)]\n  .map((m) => m[1])\n  .filter((oid) => !oid.startsWith(\"2.5.29.\")); // outside standard ext arc\nif (unknownCritical.length) throw new Error(\"nonstandard critical extension(s): \" + unknownCritical.join(\", \"));","typeGuard":"function isUnhandledCriticalExt(e: unknown): e is Error & { code: \"UNHANDLED_CRITICAL_EXTENSION\" } {\n  return e instanceof Error && (e as any).code === \"UNHANDLED_CRITICAL_EXTENSION\";\n}","tryCatchPattern":"try { await fetch(url); } catch (e) { if (isUnhandledCriticalExt(e)) { openCertTicket(new URL(url).host, \"nonstandard critical extension\"); throw e; } throw e; }","preventionTips":["Never mark private-OID extensions critical in issued certs","Lint issued certs for unknown critical extensions before deployment","Avoid CT pre-certificates escaping into served chains"],"tags":["tls","certificate","x509-extensions","pki","fetch"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}