{"record":{"id":"b7e1c28540831af0","repo":"oven-sh/bun","slug":"suite-b-los-not-allowed","errorCode":"SUITE_B_LOS_NOT_ALLOWED","errorMessage":"SUITE_B_LOS_NOT_ALLOWED","messagePattern":"SUITE_B_LOS_NOT_ALLOWED","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":239,"sourceCode":"    #[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\")]\n    STORE_LOOKUP,\n    #[error(\"NAME_CONSTRAINTS_WITHOUT_SANS\")]\n    NAME_CONSTRAINTS_WITHOUT_SANS,\n    #[error(\"UNKNOWN_CERTIFICATE_VERIFICATION_ERROR\")]\n    UNKNOWN_CERTIFICATE_VERIFICATION_ERROR,\n}","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L221-L257","documentation":"CertError::SUITE_B_LOS_NOT_ALLOWED maps BoringSSL X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED (verify code 60). The configured Suite B level of security (LOS) does not allow a curve used in the chain: P-384 keys are outside the 128-bit LOS profile, and P-256 outside the 192-bit one. Message: \"Suite B: curve not allowed for this LOS\".","triggerScenarios":"Verifier sets X509_V_FLAG_SUITE_B_128_LOS but the chain contains a P-384 certificate (or _192_LOS with a P-256 certificate). Suite B pins one curve strength per profile; mixing fails.","commonSituations":"Teams 'upgrading' half a chain to P-384 while the gateway runs the 128-bit flag; flag misconfiguration (192 selected where 128 intended) on defense-grade proxies; inconsistent policy between two enforcing middleboxes in the path.","solutions":["Decide the target LOS, then make every chain certificate use that curve: P-256 for 128-bit, P-384 for 192-bit","Align the flag with reality: set X509_V_FLAG_SUITE_B_128_LOS for P-256 chains, _192_LOS for P-384","Audit for mixed curves: openssl x509 -noout -text | grep 'ASN1 OID' across the chain"],"exampleFix":"# before: 128-bit LOS flag, chain contains P-384 intermediates\nverify_flags = suiteb_128\n\n# after: consistent profile - all P-256 with 128-bit LOS\nverify_flags = suiteb_128   # chain: prime256v1 throughout","handlingStrategy":"validation","validationCode":"// Assert one curve strength throughout the chain matching the intended Suite B LOS\nimport tls from \"node:tls\";\nimport { X509Certificate } from \"node:crypto\";\nexport function chainMatchesLos(host, los /* 'P-256' | 'P-384' */, 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.export({ format: \"jwk\" }).crv === los; }\n      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 isSuiteBLosNotAllowed(e): e is Error & { code: \"SUITE_B_LOS_NOT_ALLOWED\" } {\n  return e instanceof Error && (e as any).code === \"SUITE_B_LOS_NOT_ALLOWED\";\n}","tryCatchPattern":"try {\n  await fetch(url);\n} catch (e) {\n  if (e?.code === \"SUITE_B_LOS_NOT_ALLOWED\") {\n    // curve strength doesn't match the enabled LOS flag - align chain and flag\n    alignSuiteBProfile(url);\n  } else throw e;\n}","preventionTips":["Pick one LOS per environment and enforce a single curve across root/intermediate/leaf","When upgrading to 192-bit, re-key the whole chain before flipping the flag","Config-review Suite B flags on gateways whenever chain strength changes"],"tags":["tls","x509","suite-b","curves","compliance","fetch","security"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}