{"record":{"id":"29e065787fe2fc21","repo":"oven-sh/bun","slug":"suite-b-invalid-algorithm","errorCode":"SUITE_B_INVALID_ALGORITHM","errorMessage":"SUITE_B_INVALID_ALGORITHM","messagePattern":"SUITE_B_INVALID_ALGORITHM","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":233,"sourceCode":"    #[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\")]\n    UNSUPPORTED_CONSTRAINT_TYPE,\n    #[error(\"UNSUPPORTED_CONSTRAINT_SYNTAX\")]\n    UNSUPPORTED_CONSTRAINT_SYNTAX,\n    #[error(\"UNSUPPORTED_NAME_SYNTAX\")]\n    UNSUPPORTED_NAME_SYNTAX,\n    #[error(\"CRL_PATH_VALIDATION_ERROR\")]\n    CRL_PATH_VALIDATION_ERROR,\n    #[error(\"SUITE_B_INVALID_VERSION\")]\n    SUITE_B_INVALID_VERSION,\n    #[error(\"SUITE_B_INVALID_ALGORITHM\")]\n    SUITE_B_INVALID_ALGORITHM,\n    #[error(\"SUITE_B_INVALID_CURVE\")]\n    SUITE_B_INVALID_CURVE,\n    #[error(\"SUITE_B_INVALID_SIGNATURE_ALGORITHM\")]\n    SUITE_B_INVALID_SIGNATURE_ALGORITHM,\n    #[error(\"SUITE_B_LOS_NOT_ALLOWED\")]\n    SUITE_B_LOS_NOT_ALLOWED,\n    #[error(\"SUITE_B_CANNOT_SIGN_P_384_WITH_P_256\")]\n    SUITE_B_CANNOT_SIGN_P_384_WITH_P_256,\n    #[error(\"HOSTNAME_MISMATCH\")]\n    HOSTNAME_MISMATCH,\n    #[error(\"EMAIL_MISMATCH\")]\n    EMAIL_MISMATCH,\n    #[error(\"IP_ADDRESS_MISMATCH\")]\n    IP_ADDRESS_MISMATCH,\n    #[error(\"INVALID_CALL\")]\n    INVALID_CALL,\n    #[error(\"STORE_LOOKUP\")]","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L215-L251","documentation":"CertError::SUITE_B_INVALID_ALGORITHM maps BoringSSL X509_V_ERR_SUITE_B_INVALID_ALGORITHM (verify code 57). Suite B verification requires ECDSA public keys throughout the chain; a certificate in the chain uses another algorithm (RSA, DSA, Ed25519). Message: \"Suite B: invalid public key algorithm\".","triggerScenarios":"Suite B flags enabled on the verifier and any chain certificate carries an RSA key - typically a legacy RSA intermediate or leaf in front of an ECDSA-rooted hierarchy.","commonSituations":"Mixed-algorithm chains during incremental ECDSA migration; Suite B gateways in defense networks; default RSA certs (many CAs' default issuance) hitting a Suite B-verifying endpoint.","solutions":["Find the offending cert: openssl x509 -noout -text | grep 'Public Key Algorithm' across the chain","Reissue every chain certificate with ECDSA keys (P-256 or P-384)","Or disable Suite B flags on the verifying stack if the profile is not mandated"],"exampleFix":"# before\nopenssl req -x509 -newkey rsa:2048 ...\n\n# after: ECDSA per Suite B\nopenssl ecparam -name prime256v1 -genkey -out key.pem\nopenssl req -x509 -key key.pem ...","handlingStrategy":"validation","validationCode":"// Assert all chain certs use ECDSA when a Suite B verifier will connect\nimport tls from \"node:tls\";\nimport { X509Certificate } from \"node:crypto\";\nexport function chainIsAllEcdsa(host, port = 443) {\n  return new Promise((resolve, reject) => {\n    const s = tls.connect({ host, port, servername: host, rejectUnauthorized: false }, () => {\n      let c = s.getPeerCertificate(true), ok = true;\n      do { ok = ok && new X509Certificate(c.raw).keyObject.asymmetricKeyType === \"ec\"; } while (c.issuerCertificate && (c = c.issuerCertificate) && !Object.is(c, s.getPeerCertificate(true)));\n      s.end(); resolve(ok);\n    });\n    s.on(\"error\", reject);\n  });\n}","typeGuard":"export function isSuiteBInvalidAlgorithm(e): e is Error & { code: \"SUITE_B_INVALID_ALGORITHM\" } {\n  return e instanceof Error && (e as any).code === \"SUITE_B_INVALID_ALGORITHM\";\n}","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (e?.code === \"SUITE_B_INVALID_ALGORITHM\") {\n    // an RSA (or other non-ECDSA) cert is in the chain under Suite B - reissue with ECDSA\n    planReissueToEcdsa(new URL(url).hostname);\n  } else throw e;\n}","preventionTips":["Finish ECDSA migrations end-to-end: root, intermediates, leaf - partial migration fails Suite B","Set ECDSA as the default key type in your CA issuance pipeline if Suite B clients exist","Grep public-key algorithms across the served chain monthly: openssl s_client -showcerts | grep 'Public Key Algorithm'"],"tags":["tls","x509","suite-b","ecdsa","pki","fetch","security"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}