oven-sh/bun · error · CertError

AKID_SKID_MISMATCH

AKID_SKID_MISMATCH

Error message

AKID_SKID_MISMATCH

What it means

CertError::AKID_SKID_MISMATCH maps BoringSSL X509 verify code 30 (X509_V_ERR_AKID_SKID_MISMATCH) via get_cert_error_from_no() in src/http/lib.rs:1549. The child certificate's Authority Key Identifier does not match the Subject Key Identifier of the certificate claiming to issue it — names match but keys do not. JS error.code is AKID_SKID_MISMATCH with message 'authority and subject key identifier mismatch' (FetchTasklet.rs:1472).

Source

Thrown at src/http/error.rs:181

    #[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")]
    AKID_ISSUER_SERIAL_MISMATCH,
    #[error("KEYUSAGE_NO_CERTSIGN")]
    KEYUSAGE_NO_CERTSIGN,
    #[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")]

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Compare identifiers: leaf AKI (openssl x509 -noout -text | grep -A1 'Authority Key') vs intermediate SKI — must match
  2. Download the CURRENT intermediate from the CA's AIA URL embedded in the leaf and rebuild fullchain.pem
  3. If you control the PKI and re-keyed the CA, reissue leafs or serve both old and new chains during migration
  4. Clear any pinned intermediate from the client side (tls: { ca }) and let chain building use the served path

Example fix

# before
leaf(issued by new-key-int) + old-key-int.pem
# after
leaf.pem + new-key-int.pem
# follow the leaf's AIA pointer to fetch the matching intermediate
openssl x509 -in leaf.pem -noout -text | grep -A1 'Authority Information Access'
Defensive patterns

Strategy: validation

Validate before calling

import { X509Certificate } from "node:crypto";
const leaf = new X509Certificate(await Bun.file("leaf.pem").text());
const int = new X509Certificate(await Bun.file("intermediate.pem").text());
const leafAki = leaf.toString().match(/Signature Algorithm|X509v3 Authority Key Identifier:\s*\n\s*([0-9A-F:]+)/)?.[1];
const intSki = int.toString().match(/X509v3 Subject Key Identifier:\s*\n\s*([0-9A-F:]+)/)?.[1];
if (leafAki && intSki && leafAki.replace(/:/g, "") !== intSki.replace(/:/g, "")) {
  throw new Error("leaf AKI != intermediate SKI — wrong (re-keyed?) intermediate bundled");
}

Type guard

function isAkidSkidMismatch(e: unknown): e is Error & { code: "AKID_SKID_MISMATCH" } {
  return e instanceof Error && (e as any).code === "AKID_SKID_MISMATCH";
}

Try / catch

try { await fetch(url); } catch (e) { if (isAkidSkidMismatch(e)) { refetchIntermediateFromAIA(new URL(url).host); throw e; } throw e; }

Prevention

When it happens

Trigger: CA was re-keyed (same subject DN, new key pair) and the server still serves the pre-rekey intermediate; client trusts/supplies the old-key intermediate while the leaf was signed with the new key.

Common situations: CA key rotations (e.g., cross-signed roots being re-keyed), cached intermediate bundles pinned in docker images, private PKI re-key events without reissuing or rebundling the chain.

Related errors


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