oven-sh/bun · error · TypeError

KEYUSAGE_NO_CERTSIGN

KEYUSAGE_NO_CERTSIGN

Error message

KEYUSAGE_NO_CERTSIGN

What it means

CertError::KEYUSAGE_NO_CERTSIGN maps BoringSSL X509 verify code 32 (X509_V_ERR_KEYUSAGE_NO_CERTSIGN) via get_cert_error_from_no() in src/http/lib.rs:1551. A certificate acting as an issuer in the chain has a keyUsage extension that lacks the keyCertSign bit, so it is not allowed to sign certificates. JS error.code is KEYUSAGE_NO_CERTSIGN with message 'key usage does not include certificate signing' (FetchTasklet.rs:1478).

Source

Thrown at src/http/error.rs:185

    #[error("CERT_REVOKED")]
    CERT_REVOKED,
    #[error("INVALID_CA")]
    INVALID_CA,
    #[error("PATH_LENGTH_EXCEEDED")]
    PATH_LENGTH_EXCEEDED,
    #[error("INVALID_PURPOSE")]
    INVALID_PURPOSE,
    #[error("CERT_UNTRUSTED")]
    CERT_UNTRUSTED,
    #[error("CERT_REJECTED")]
    CERT_REJECTED,
    #[error("SUBJECT_ISSUER_MISMATCH")]
    SUBJECT_ISSUER_MISMATCH,
    #[error("AKID_SKID_MISMATCH")]
    AKID_SKID_MISMATCH,
    #[error("AKID_ISSUER_SERIAL_MISMATCH")]
    AKID_ISSUER_SERIAL_MISMATCH,
    #[error("KEYUSAGE_NO_CERTSIGN")]
    KEYUSAGE_NO_CERTSIGN,
    #[error("UNABLE_TO_GET_CRL_ISSUER")]
    UNABLE_TO_GET_CRL_ISSUER,
    #[error("UNHANDLED_CRITICAL_EXTENSION")]
    UNHANDLED_CRITICAL_EXTENSION,
    #[error("KEYUSAGE_NO_CRL_SIGN")]
    KEYUSAGE_NO_CRL_SIGN,
    #[error("UNHANDLED_CRITICAL_CRL_EXTENSION")]
    UNHANDLED_CRITICAL_CRL_EXTENSION,
    #[error("INVALID_NON_CA")]
    INVALID_NON_CA,
    #[error("PROXY_PATH_LENGTH_EXCEEDED")]
    PROXY_PATH_LENGTH_EXCEEDED,
    #[error("KEYUSAGE_NO_DIGITAL_SIGNATURE")]
    KEYUSAGE_NO_DIGITAL_SIGNATURE,
    #[error("PROXY_CERTIFICATES_NOT_ALLOWED")]
    PROXY_CERTIFICATES_NOT_ALLOWED,
    #[error("INVALID_EXTENSION")]

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Inspect the issuer's keyUsage: openssl x509 -in ca.pem -noout -text | grep -A1 'Key Usage' — must include Certificate Sign
  2. Regenerate the CA with keyUsage=critical,keyCertSign,cRLSign and reissue everything beneath it
  3. Never sign certs with a leaf; provision a real CA cert for issuing
  4. Re-verify: openssl verify -CAfile new-ca.pem leaf.pem

Example fix

# before: CA without keyCertSign
openssl req -x509 -newkey rsa:2048 -keyout k.pem -out ca.pem \
  -addext 'keyUsage=digitalSignature'
# after
openssl req -x509 -newkey rsa:2048 -keyout k.pem -out ca.pem -days 3650 \
  -addext 'keyUsage=critical,keyCertSign,cRLSign' \
  -addext 'basicConstraints=critical,CA:TRUE'
Defensive patterns

Strategy: validation

Validate before calling

import { X509Certificate } from "node:crypto";
const ca = new X509Certificate(await Bun.file("ca.pem").text());
const text = await Bun.$`openssl x509 -in ca.pem -noout -text`.text();
if (!/Certificate Sign/.test(text)) {
  throw new Error("issuing cert lacks keyCertSign — it must not sign certificates");
}

Type guard

function isNoCertSign(e: unknown): e is Error & { code: "KEYUSAGE_NO_CERTSIGN" } {
  return e instanceof Error && (e as any).code === "KEYUSAGE_NO_CERTSIGN";
}

Try / catch

try { await fetch(url); } catch (e) { if (isNoCertSign(e)) { alertPkiTeam("issuer missing keyCertSign on chain for " + new URL(url).host); throw e; } throw e; }

Prevention

When it happens

Trigger: Self-signed cert minted with keyUsage=digitalSignature (or default restrictive usage) then used to sign another cert; intermediate template missing keyCertSign; leaf certs used as ad-hoc CAs in test harnesses.

Common situations: Local dev scripts generating a 'CA' with openssl req -x509 and a restrictive -addext keyUsage, PKI templates cloned from server-cert profiles, mkcert-style workflows reimplemented incorrectly.

Understand the failure class

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/44e0dca4d67fe09b. Report an issue: GitHub.