oven-sh/bun · error · CertError
SELF_SIGNED_CERT_IN_CHAIN
SELF_SIGNED_CERT_IN_CHAIN
Error message
SELF_SIGNED_CERT_IN_CHAIN
What it means
X509 verify result 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN): a self-signed certificate was found in the chain (typically the root, or a corporate intermediate) but it is not in the local trust store, so the chain cannot be anchored. Mapped via get_cert_error_from_no (src/http/lib.rs:1538) to CertError::SELF_SIGNED_CERT_IN_CHAIN.
Source
Thrown at src/http/error.rs:159
#[error("CERT_HAS_EXPIRED")]
CERT_HAS_EXPIRED,
#[error("CRL_NOT_YET_VALID")]
CRL_NOT_YET_VALID,
#[error("CRL_HAS_EXPIRED")]
CRL_HAS_EXPIRED,
#[error("ERROR_IN_CERT_NOT_BEFORE_FIELD")]
ERROR_IN_CERT_NOT_BEFORE_FIELD,
#[error("ERROR_IN_CERT_NOT_AFTER_FIELD")]
ERROR_IN_CERT_NOT_AFTER_FIELD,
#[error("ERROR_IN_CRL_LAST_UPDATE_FIELD")]
ERROR_IN_CRL_LAST_UPDATE_FIELD,
#[error("ERROR_IN_CRL_NEXT_UPDATE_FIELD")]
ERROR_IN_CRL_NEXT_UPDATE_FIELD,
#[error("OUT_OF_MEM")]
OUT_OF_MEM,
#[error("DEPTH_ZERO_SELF_SIGNED_CERT")]
DEPTH_ZERO_SELF_SIGNED_CERT,
#[error("SELF_SIGNED_CERT_IN_CHAIN")]
SELF_SIGNED_CERT_IN_CHAIN,
#[error("UNABLE_TO_GET_ISSUER_CERT_LOCALLY")]
UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
#[error("UNABLE_TO_VERIFY_LEAF_SIGNATURE")]
UNABLE_TO_VERIFY_LEAF_SIGNATURE,
#[error("CERT_CHAIN_TOO_LONG")]
CERT_CHAIN_TOO_LONG,
#[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")]View on GitHub (pinned to 8c5296ac45)
Solutions
- Install the corporate/private root CA: export it and point Bun at it via NODE_EXTRA_CA_CERTS=/path/to/corp-root.pem, or pass fetch(url, { tls: { ca: corpRootPem } })
- Fix the server to not send the self-signed root in the chain (leaf + intermediates only) — clients that already trust the root then verify fine
- In containers, bake the company root into the image's CA store
- Only as a last resort: rejectUnauthorized: false, understanding it disables all peer verification
Example fix
# before
await fetch("https://internal.corp/api"); // SELF_SIGNED_CERT_IN_CHAIN
# after
NODE_EXTRA_CA_CERTS=/usr/local/share/corp-root.pem bun run app.ts Defensive patterns
Strategy: try-catch
Validate before calling
// fail fast at boot if a corporate root is configured but unreadable
import { readFileSync, existsSync } from "node:fs";
const corpCa = process.env.NODE_EXTRA_CA_CERTS;
if (corpCa && !existsSync(corpCa)) throw new Error(`NODE_EXTRA_CA_CERTS points to missing file: ${corpCa}`); Type guard
function isCertErrorCode(e: unknown, code = "SELF_SIGNED_CERT_IN_CHAIN"): e is Error & { code: string } {
return e instanceof Error && (e as any).code === code;
} Try / catch
try {
await fetch("https://internal.corp/api");
} catch (e) {
if (isCertErrorCode(e, "SELF_SIGNED_CERT_IN_CHAIN")) {
// corporate proxy root not trusted — load it explicitly instead of disabling verification
const res = await fetch("https://internal.corp/api", {
tls: { ca: readFileSync("/usr/local/share/corp-root.pem", "utf8") },
});
} else throw e;
} Prevention
- Distribute the corporate root via NODE_EXTRA_CA_CERTS in your base image/CI templates
- Don't disable verification to work around SSL-inspection proxies — trust the proxy root instead
- Configure servers to omit the self-signed root from the served chain
When it happens
Trigger: TLS handshake where the server sends its full chain including the self-signed root (unnecessary but common), and that root is absent from Bun's CA bundle — typical behind corporate TLS-inspecting proxies (Zscaler, Netskope, Blue Coat) or with private CAs.
Common situations: Corporate laptops behind SSL-inspection proxies whose root CA isn't installed for Bun, containers missing the company root, private service meshes whose root isn't distributed, or servers configured to send root.pem in the chain.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- UNABLE_TO_GET_ISSUER_CERT
- UNABLE_TO_DECRYPT_CERT_SIGNATURE
- UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
- CERT_SIGNATURE_FAILURE
- ERROR_IN_CERT_NOT_BEFORE_FIELD
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/02ea67ee55bf53f2.
Report an issue: GitHub.