oven-sh/bun · error · TypeError
PERMITTED_VIOLATION
PERMITTED_VIOLATION
Error message
PERMITTED_VIOLATION
What it means
CertError::PERMITTED_VIOLATION maps BoringSSL X509_V_ERR_PERMITTED_VIOLATION (verify code 47). A CA in the chain carries a nameConstraints extension with permittedSubtrees, and the name being validated (SAN/subject of a lower cert) falls outside every permitted subtree. Message: "permitted subtree violation".
Source
Thrown at src/http/error.rs:215
#[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")]
INVALID_EXTENSION,
#[error("INVALID_POLICY_EXTENSION")]
INVALID_POLICY_EXTENSION,
#[error("NO_EXPLICIT_POLICY")]
NO_EXPLICIT_POLICY,
#[error("DIFFERENT_CRL_SCOPE")]
DIFFERENT_CRL_SCOPE,
#[error("UNSUPPORTED_EXTENSION_FEATURE")]
UNSUPPORTED_EXTENSION_FEATURE,
#[error("UNNESTED_RESOURCE")]
UNNESTED_RESOURCE,
#[error("PERMITTED_VIOLATION")]
PERMITTED_VIOLATION,
#[error("EXCLUDED_VIOLATION")]
EXCLUDED_VIOLATION,
#[error("SUBTREE_MINMAX")]
SUBTREE_MINMAX,
#[error("APPLICATION_VERIFICATION")]
APPLICATION_VERIFICATION,
#[error("UNSUPPORTED_CONSTRAINT_TYPE")]
UNSUPPORTED_CONSTRAINT_TYPE,
#[error("UNSUPPORTED_CONSTRAINT_SYNTAX")]
UNSUPPORTED_CONSTRAINT_SYNTAX,
#[error("UNSUPPORTED_NAME_SYNTAX")]
UNSUPPORTED_NAME_SYNTAX,
#[error("CRL_PATH_VALIDATION_ERROR")]
CRL_PATH_VALIDATION_ERROR,
#[error("SUITE_B_INVALID_VERSION")]
SUITE_B_INVALID_VERSION,
#[error("SUITE_B_INVALID_ALGORITHM")]View on GitHub (pinned to 8c5296ac45)
Solutions
- Print the constraints: openssl x509 -in ca.pem -noout -text and read the Name Constraints permitted subtrees
- Reissue the leaf with only names inside the permitted subtrees (drop the offending SAN)
- Or widen the CA's permittedSubtrees to include the name and reissue the CA chain
- Verify the chain locally: openssl verify -CAfile constrained-ca.pem leaf.pem
Example fix
# before: CA permits DNS:corp.example.com ; leaf requests a foreign SAN [leaf_ext] subjectAltName = DNS:api.corp.example.com, DNS:api.partner.org # after: SANs within the permitted subtree [leaf_ext] subjectAltName = DNS:api.corp.example.com
Defensive patterns
Strategy: validation
Validate before calling
// Before issuing/before trusting: check the SAN sits inside the CA's permitted subtrees
import { X509Certificate } from "node:crypto";
export function sanWithinPermitted(leafPem, caPem, permitted /* e.g. ["corp.example.com"] */) {
const leaf = new X509Certificate(leafPem);
const ca = new X509Certificate(caPem);
if (!/(Name Constraints|permittedSubtrees)/i.test(ca.toString())) return true; // unconstrained
const dns = (leaf.subjectAltName ?? "").match(/DNS:([^,\s]+)/g)?.map((s) => s.slice(4)) ?? [];
return dns.every((name) => permitted.some((p) => name === p || name.endsWith("." + p)));
} Type guard
export function isPermittedViolation(e): e is Error & { code: "PERMITTED_VIOLATION" } {
return e instanceof Error && (e as any).code === "PERMITTED_VIOLATION";
} Try / catch
try {
await fetch(url);
} catch (e) {
if (e?.code === "PERMITTED_VIOLATION") {
// SAN is outside the CA's permittedSubtrees - reissue leaf or widen the CA
reportToCaOwner(new URL(url).hostname);
} else throw e;
} Prevention
- Encode the CA's permitted subtrees as data in your issuance pipeline and assert every SAN against them pre-signing
- When acquiring domains, update nameConstraints before issuing certs for the new names
- Prefer unconstrained public CAs for public names; use constrained CAs only where the policy is enforced end-to-end
When it happens
Trigger: CA has nameConstraints permittedSubtrees = DNS:example.com, but a cert under it was issued with SAN www.other.org (or an IP/email/URI outside the permitted list). Any name present in the cert that is constrained must match a permitted subtree.
Common situations: Internal CAs constrained to corporate domains asked to sign certs for a new/acquired domain; CA templates copied between unconstrained and constrained hierarchies; mixing an enterprise intermediate under a constrained public root.
Related errors
- EXCLUDED_VIOLATION
- SUBTREE_MINMAX
- UNSUPPORTED_CONSTRAINT_TYPE
- UNSUPPORTED_CONSTRAINT_SYNTAX
- NO_EXPLICIT_POLICY
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/e4b779f6ed0047c1.
Report an issue: GitHub.