{"record":{"id":"1d0ee458bbb2941d","repo":"oven-sh/bun","slug":"proxy-certificates-not-allowed","errorCode":"PROXY_CERTIFICATES_NOT_ALLOWED","errorMessage":"PROXY_CERTIFICATES_NOT_ALLOWED","messagePattern":"PROXY_CERTIFICATES_NOT_ALLOWED","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":201,"sourceCode":"    #[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\")]\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\")]","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L183-L219","documentation":"CertError::PROXY_CERTIFICATES_NOT_ALLOWED maps BoringSSL X509 verify code 40 (X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED) via get_cert_error_from_no() in src/http/lib.rs:1559. RFC 3820 proxy certificates were found in the chain, but proxy-certificate acceptance is not enabled for this verification context (BoringSSL's X509_V_FLAG_ALLOW_PROXY_CERTS is off), so the chain fails. JS error.code is PROXY_CERTIFICATES_NOT_ALLOWED with message 'proxy certificates not allowed, please set the appropriate flag' (FetchTasklet.rs:1452).","triggerScenarios":"TLS endpoint presents a chain containing proxy certificates (proxyCertInfo extension, grid/VO proxies); Bun's fetch/Bun.connect verification contexts never set the allow-proxy flag, so any proxy cert aborts verification.","commonSituations":"Grid computing / science-Gateway endpoints that expect X.509 proxy auth, delegated-credential experiments, proxies accidentally bundled into fullchain.pem by pipeline tooling.","solutions":["Remove proxy certificates from the chain served to fetch(); present the plain end-entity chain","Terminate the proxy at a gateway that presents a normal TLS cert (gateway holds the proxy, not the browser/fetch client)","Reissue the endpoint with a standard server certificate (no proxyCertInfo extension)","There is no fetch() option to enable proxy certs — do not attempt to bypass with rejectUnauthorized:false outside throwaway tests"],"exampleFix":"# before: fullchain.pem = proxy.pem + ee.pem + int.pem\n# after: fullchain.pem = ee.pem + int.pem\n# proxy credentials move to the application layer (Authorization header), not TLS\nawait fetch(\"https://gateway.example.org/job\", {\n  headers: { Authorization: `Bearer ${proxyToken}` },\n});","handlingStrategy":"try-catch","validationCode":"import { X509Certificate } from \"node:crypto\";\nconst cert = new X509Certificate(await Bun.file(\"cert.pem\").text());\nconst text = await Bun.$`openssl x509 -in cert.pem -noout -text`.text();\nif (/Proxy Certificate Information|proxyCertInfo/i.test(text)) {\n  throw new Error(\"proxy cert in chain — fetch() verification cannot allow proxy certificates\");\n}","typeGuard":"function isProxyCertsNotAllowed(e: unknown): e is Error & { code: \"PROXY_CERTIFICATES_NOT_ALLOWED\" } {\n  return e instanceof Error && (e as any).code === \"PROXY_CERTIFICATES_NOT_ALLOWED\";\n}","tryCatchPattern":"try { await fetch(url); } catch (e) { if (isProxyCertsNotAllowed(e)) { routeViaGatewayWithoutProxyCert(url); throw e; } throw e; }","preventionTips":["Keep RFC 3820 proxy certs out of served TLS chains","Move delegation credentials to application-layer headers","Use plain server certificates for fetch()-reachable endpoints"],"tags":["tls","certificate","proxy-cert","rfc3820","fetch"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}