{"record":{"id":"041dd66bbf4be1b0","repo":"oven-sh/bun","slug":"unable-to-decode-issuer-public-key","errorCode":null,"errorMessage":"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY","messagePattern":"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY","errorType":"error_code","errorClass":"CertError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":133,"sourceCode":"    Zstd(bun_zstd::ZstdError),\n    #[error(transparent)]\n    Picohttp(bun_picohttp::ParseResponseError),\n}\n\n#[allow(non_camel_case_types)]\n#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error, strum::IntoStaticStr)]\npub enum CertError {\n    #[error(\"OK\")]\n    OK,\n    #[error(\"UNABLE_TO_GET_ISSUER_CERT\")]\n    UNABLE_TO_GET_ISSUER_CERT,\n    #[error(\"UNABLE_TO_GET_CRL\")]\n    UNABLE_TO_GET_CRL,\n    #[error(\"UNABLE_TO_DECRYPT_CERT_SIGNATURE\")]\n    UNABLE_TO_DECRYPT_CERT_SIGNATURE,\n    #[error(\"UNABLE_TO_DECRYPT_CRL_SIGNATURE\")]\n    UNABLE_TO_DECRYPT_CRL_SIGNATURE,\n    #[error(\"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY\")]\n    UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY,\n    #[error(\"CERT_SIGNATURE_FAILURE\")]\n    CERT_SIGNATURE_FAILURE,\n    #[error(\"CRL_SIGNATURE_FAILURE\")]\n    CRL_SIGNATURE_FAILURE,\n    #[error(\"CERT_NOT_YET_VALID\")]\n    CERT_NOT_YET_VALID,\n    #[error(\"CERT_HAS_EXPIRED\")]\n    CERT_HAS_EXPIRED,\n    #[error(\"CRL_NOT_YET_VALID\")]\n    CRL_NOT_YET_VALID,\n    #[error(\"CRL_HAS_EXPIRED\")]\n    CRL_HAS_EXPIRED,\n    #[error(\"ERROR_IN_CERT_NOT_BEFORE_FIELD\")]\n    ERROR_IN_CERT_NOT_BEFORE_FIELD,\n    #[error(\"ERROR_IN_CERT_NOT_AFTER_FIELD\")]\n    ERROR_IN_CERT_NOT_AFTER_FIELD,\n    #[error(\"ERROR_IN_CRL_LAST_UPDATE_FIELD\")]","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L115-L151","documentation":"X509 verify result 6 (X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY): the issuer certificate's public key could not be decoded (bad SubjectPublicKeyInfo), so signatures cannot be checked. Mapped via get_cert_error_from_no (src/http/lib.rs:1525) to CertError::UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY, message \"unable to decode issuer public key\" (FetchTasklet.rs:1388).","triggerScenarios":"TLS handshake where the intermediate/CA certificate presented (or supplied via tls.ca / NODE_EXTRA_CA_CERTS) is malformed — truncated PEM, wrong file contents, or a DER/PEM mixup.","commonSituations":"A truncated or hand-edited CA bundle, pasting an HTML page instead of the PEM, appending binary DER data into a .pem file, or supplying a chain file where a key file was expected.","solutions":["Re-download the CA/intermediate from the authoritative source and validate: openssl x509 -in ca.pem -noout -text","Check the supplied tls.ca / NODE_EXTRA_CA_CERTS file: every block must be a complete -----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----","Convert DER to PEM properly if needed: openssl x509 -inform DER -in ca.der -out ca.pem","Remove the corrupt entry and retry to isolate which file is broken"],"exampleFix":"// before: accidental key file passed as CA\nawait fetch(url, { tls: { ca: readFileSync(\"ca.key\", \"utf8\") } });\n\n// after\nawait fetch(url, { tls: { ca: readFileSync(\"ca.pem\", \"utf8\") } });","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction loadCaBundle(path: string): string {\n  const pem = readFileSync(path, \"utf8\");\n  const blocks = pem.match(/-----BEGIN CERTIFICATE-----[\\s\\S]*?-----END CERTIFICATE-----/g) ?? [];\n  if (blocks.length === 0) throw new Error(`CA bundle '${path}' contains no valid PEM certificates`);\n  return blocks.join(\"\\n\");\n}\nconst ca = loadCaBundle(\"./ca.pem\"); // fails fast before any fetch\nawait fetch(url, { tls: { ca } });","typeGuard":"function isCertErrorCode(e: unknown, code = \"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY\"): e is Error & { code: string } {\n  return e instanceof Error && (e as any).code === code;\n}","tryCatchPattern":"try {\n  await fetch(url, { tls: { ca } });\n} catch (e) {\n  if (isCertErrorCode(e, \"UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY\")) {\n    // the CA/intermediate you supplied is malformed — fix the bundle, don't retry\n    throw new Error(\"Provided CA bundle contains a malformed certificate\");\n  }\n  throw e;\n}","preventionTips":["Validate PEM bundles at startup with a BEGIN/END block parser","Fetch CA files from authoritative sources; never hand-edit","Use openssl x509 -noout -text in CI to prove every bundle member parses"],"tags":["tls","certificates","pkix","fetch","configuration"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}