oven-sh/bun · error · TypeError

INVALID_POLICY_EXTENSION

INVALID_POLICY_EXTENSION

Error message

INVALID_POLICY_EXTENSION

What it means

CertError::INVALID_POLICY_EXTENSION maps BoringSSL X509_V_ERR_INVALID_POLICY_EXTENSION (verify code 42). It means the certificatePolicies extension (OID 2.5.29.32) in a chain certificate is malformed or inconsistent: bad policy OID encoding, duplicate PolicyInformation entries, or an invalid policy qualifier. Surfaces through fetch() as code "INVALID_POLICY_EXTENSION" with message "invalid or inconsistent certificate policy extension".

Source

Thrown at src/http/error.rs:205

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

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Inspect the extension: openssl x509 -in cert.pem -noout -text and check the 'X509v3 Certificate Policies' block for malformed/duplicate OIDs
  2. Reissue the certificate with a well-formed certificatePolicies extension (one entry per policy OID, valid qualifier types)
  3. If the policy is not needed, reissue without the certificatePolicies extension entirely
  4. Validate offline before deploying: openssl verify -CAfile chain.pem leaf.pem

Example fix

# before: duplicate policy OID
authorityInfoAccess = OCSP;URI:http://ocsp.example.com
[v3_policies]
certificatePolicies = 2.23.140.1.2.1, 2.23.140.1.2.1

# after: single occurrence
[v3_policies]
certificatePolicies = 2.23.140.1.2.1
Defensive patterns

Strategy: try-catch

Validate before calling

// Check certificatePolicies parses and has no duplicate OIDs before trusting the endpoint
import { execFileSync } from "node:child_process";
export function lintPolicies(certPem) {
  const txt = execFileSync("openssl", ["x509", "-noout", "-text"], { input: certPem }).toString();
  const block = txt.split("X509v3 Certificate Policies:")[1]?.split(/\n\n/)[0] ?? "";
  const oids = [...block.matchAll(/Policy: ([0-9.]+)/g)].map((m) => m[1]);
  if (oids.length !== new Set(oids).size) throw new Error("duplicate policy OID in certificatePolicies");
}

Type guard

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

Try / catch

try {
  await fetch(url);
} catch (e) {
  if (e?.code === "INVALID_POLICY_EXTENSION") {
    // certificatePolicies extension is malformed - CA must reissue the cert
    logCertDefect(hostname, "policies-extension");
  } else throw e;
}

Prevention

When it happens

Trigger: TLS handshake to a server whose cert (or an intermediate) carries a certificatePolicies extension that fails RFC 5280 parsing: truncated policy OIDs, the same policy OID listed twice, anyPolicy mixed with other policies incorrectly, or qualifier syntax errors.

Common situations: Private PKIs generated by custom tooling (python cryptography misuse, hand-built ASN.1); some CA appliances that emit duplicate policy OIDs; test CAs created before a toolchain fixed its policy encoder.

Related errors


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