{"record":{"id":"d530772b91b51c1e","repo":"oven-sh/bun","slug":"invalid-policy-extension","errorCode":"INVALID_POLICY_EXTENSION","errorMessage":"INVALID_POLICY_EXTENSION","messagePattern":"INVALID_POLICY_EXTENSION","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":205,"sourceCode":"    #[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\")]\n    NO_EXPLICIT_POLICY,\n    #[error(\"DIFFERENT_CRL_SCOPE\")]\n    DIFFERENT_CRL_SCOPE,\n    #[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\")]","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L187-L223","documentation":"CertError::INVALID_POLICY_EXTENSION maps BoringSSL X509_V_ERR_INVALID_POLICY_EXTENSION (verify code 42). It means the certificatePolicies extension (OID 2.5.29.32) in a chain certificate is malformed or inconsistent: bad policy OID encoding, duplicate PolicyInformation entries, or an invalid policy qualifier. Surfaces through fetch() as code \"INVALID_POLICY_EXTENSION\" with message \"invalid or inconsistent certificate policy extension\".","triggerScenarios":"TLS handshake to a server whose cert (or an intermediate) carries a certificatePolicies extension that fails RFC 5280 parsing: truncated policy OIDs, the same policy OID listed twice, anyPolicy mixed with other policies incorrectly, or qualifier syntax errors.","commonSituations":"Private PKIs generated by custom tooling (python cryptography misuse, hand-built ASN.1); some CA appliances that emit duplicate policy OIDs; test CAs created before a toolchain fixed its policy encoder.","solutions":["Inspect the extension: openssl x509 -in cert.pem -noout -text and check the 'X509v3 Certificate Policies' block for malformed/duplicate OIDs","Reissue the certificate with a well-formed certificatePolicies extension (one entry per policy OID, valid qualifier types)","If the policy is not needed, reissue without the certificatePolicies extension entirely","Validate offline before deploying: openssl verify -CAfile chain.pem leaf.pem"],"exampleFix":"# before: duplicate policy OID\nauthorityInfoAccess = OCSP;URI:http://ocsp.example.com\n[v3_policies]\ncertificatePolicies = 2.23.140.1.2.1, 2.23.140.1.2.1\n\n# after: single occurrence\n[v3_policies]\ncertificatePolicies = 2.23.140.1.2.1","handlingStrategy":"try-catch","validationCode":"// Check certificatePolicies parses and has no duplicate OIDs before trusting the endpoint\nimport { execFileSync } from \"node:child_process\";\nexport function lintPolicies(certPem) {\n  const txt = execFileSync(\"openssl\", [\"x509\", \"-noout\", \"-text\"], { input: certPem }).toString();\n  const block = txt.split(\"X509v3 Certificate Policies:\")[1]?.split(/\\n\\n/)[0] ?? \"\";\n  const oids = [...block.matchAll(/Policy: ([0-9.]+)/g)].map((m) => m[1]);\n  if (oids.length !== new Set(oids).size) throw new Error(\"duplicate policy OID in certificatePolicies\");\n}","typeGuard":"export function isInvalidPolicyExtension(e): e is Error & { code: \"INVALID_POLICY_EXTENSION\" } {\n  return e instanceof Error && (e as any).code === \"INVALID_POLICY_EXTENSION\";\n}","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (e?.code === \"INVALID_POLICY_EXTENSION\") {\n    // certificatePolicies extension is malformed - CA must reissue the cert\n    logCertDefect(hostname, \"policies-extension\");\n  } else throw e;\n}","preventionTips":["Validate certificatePolicies on every cert your CA issues (openssl x509 -text + OID lint) in issuance CI","Never hand-write policy extension ASN.1; use declarative configs","Monitor TLS endpoints with scheduled openssl s_client probes so malformed certs are caught before users"],"tags":["tls","x509","certificate-policies","fetch","security","asn1"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}