oven-sh/bun · error · TypeError

NO_EXPLICIT_POLICY

NO_EXPLICIT_POLICY

Error message

NO_EXPLICIT_POLICY

What it means

CertError::NO_EXPLICIT_POLICY maps BoringSSL X509_V_ERR_NO_EXPLICIT_POLICY (verify code 43). RFC 5280 policy processing ended with no explicit certificate policy while the verification context requires one (explicit-policy indicator set on the trust anchor / verify params). Bun surfaces it as code "NO_EXPLICIT_POLICY", message "no explicit policy".

Source

Thrown at src/http/error.rs:207

    #[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")]
    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")]

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Reissue the leaf/intermediates with the required policy OID in certificatePolicies (e.g. 2.23.140.1.2.1 for DV)
  2. On the verifying side, drop the explicit-policy requirement (remove X509_V_FLAG_POLICY_CHECK / initial-explicit-policy) if policy matching is not actually mandated
  3. Check that the trust anchor is the intended one - pointing at a policy-constrained root for a public endpoint causes exactly this
  4. Confirm with openssl verify -policy <oid> -CAfile ca.pem leaf.pem which cert in the chain lacks the policy

Example fix

# before: leaf template without policies (fails when anchor requires explicit policy)
[v3]
basicConstraints = critical, CA:FALSE
subjectAltName = DNS:example.com

# after: include the required policy
[v3]
basicConstraints = critical, CA:FALSE
subjectAltName = DNS:example.com
certificatePolicies = 1.2.3.4.5, 2.23.140.1.2.1
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the chain satisfies the required policy OID before the real request
import { execFileSync } from "node:child_process";
export function chainHasPolicy(certPem, caPem, oid) {
  execFileSync("openssl", ["verify", "-policy", oid, "-CAfile", caPem, "-untrusted", certPem, certPem], { stdio: "pipe" });
  return true; // throws if no acceptable policy
}

Type guard

export function isNoExplicitPolicy(e): e is Error & { code: "NO_EXPLICIT_POLICY" } {
  return e instanceof Error && (e as any).code === "NO_EXPLICIT_POLICY";
}

Try / catch

try {
  await fetch(url);
} catch (e) {
  if (e?.code === "NO_EXPLICIT_POLICY") {
    // chain lacks a policy the trust anchor demands - add certificatePolicies or relax the requirement
    routeToPkiTeam(url);
  } else throw e;
}

Prevention

When it happens

Trigger: Path validation runs with policy checking and requireExplicitPolicy: every cert in the chain must then carry an acceptable certificatePolicies entry. A chain where the leaf omits certificatePolicies (or contains none of the user-initial-policy OIDs) fails with this code.

Common situations: Private/government PKIs where the root mandates a specific policy OID but leafs were issued from a template without it; verification stacks upgraded to enforce policy processing (behavior change after an OpenSSL/BoringSSL update); chains mixing public CA leafs with a constrained enterprise anchor.

Related errors


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