oven-sh/bun · error · CertError
CERT_CHAIN_TOO_LONG
CERT_CHAIN_TOO_LONG
Error message
CERT_CHAIN_TOO_LONG
What it means
CertError::CERT_CHAIN_TOO_LONG maps BoringSSL X509 verify code 22 (X509_V_ERR_CERT_CHAIN_TOO_LONG) via get_cert_error_from_no() in src/http/lib.rs:1541. The presented certificate chain exceeds the verifier's maximum chain depth, so verification aborts before reaching a trust anchor. JS error.code is CERT_CHAIN_TOO_LONG with message 'certificate chain too long' (FetchTasklet.rs:1434).
Source
Thrown at src/http/error.rs:165
#[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")]
CERT_REJECTED,
#[error("SUBJECT_ISSUER_MISMATCH")]
SUBJECT_ISSUER_MISMATCH,
#[error("AKID_SKID_MISMATCH")]
AKID_SKID_MISMATCH,
#[error("AKID_ISSUER_SERIAL_MISMATCH")]View on GitHub (pinned to 8c5296ac45)
Solutions
- Run openssl s_client -connect host:443 -showcerts and count certs; remove everything except the shortest path leaf -> intermediate(s) -> root
- Drop duplicate and cross-signed alternative paths from the served chain
- If operating the PKI, flatten the hierarchy (fewer intermediate CAs) so the path fits the depth limit
- Verify the trimmed chain locally: openssl verify -show_chain -untrusted intermediates.pem leaf.pem
Example fix
# before: fullchain.pem has leaf + 4 intermediates + 2 cross-signed variants cat leaf.pem int1.pem int2.pem > /etc/ssl/fullchain.pem # after: shortest valid path only cat leaf.pem int1.pem int2.pem root-ca.pem > /etc/ssl/fullchain.pem # then reload nginx/haproxy and re-test openssl s_client -connect example.com:443 -brief </dev/null
Defensive patterns
Strategy: validation
Validate before calling
import tls from "node:tls";
import { execSync } from "node:child_process";
function chainDepth(host: string, port = 443): number {
const out = execSync(`openssl s_client -connect ${host}:${port} -showcerts </dev/null 2>/dev/null`).toString();
return (out.match(/-----BEGIN CERTIFICATE-----/g) ?? []).length;
}
if (chainDepth("example.com") > 5) throw new Error("served chain suspiciously deep — trim fullchain.pem"); Type guard
function isChainTooLong(e: unknown): e is Error & { code: "CERT_CHAIN_TOO_LONG" } {
return e instanceof Error && (e as any).code === "CERT_CHAIN_TOO_LONG";
} Try / catch
try { await fetch(url); } catch (e) { if (isChainTooLong(e)) { alertOps("trim fullchain.pem on " + new URL(url).host); return cachedCopy(); } throw e; } Prevention
- Keep fullchain.pem to the minimal valid path; delete stale cross-signed entries
- Automate chain assembly from the CA's current bundle on renewal
- Verify chains in CI with openssl verify -show_chain
When it happens
Trigger: Server sends more intermediates than the depth limit (commonly > ~10 in BoringSSL); a cross-signed chain plus extra bundled roots in the served chain; a loop or duplicate certs in the PEM bundle sent as the chain.
Common situations: fullchain.pem assembled from multiple renewal generations, legacy cross-signed paths kept 'just in case', misconfigured load balancers concatenating several chains, internal PKI with deep sub-CA hierarchies.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/f7f499025cec68f5.
Report an issue: GitHub.