oven-sh/bun · error · TypeError

AKID_ISSUER_SERIAL_MISMATCH

AKID_ISSUER_SERIAL_MISMATCH

Error message

AKID_ISSUER_SERIAL_MISMATCH

What it means

CertError::AKID_ISSUER_SERIAL_MISMATCH maps BoringSSL X509 verify code 31 (X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH) via get_cert_error_from_no() in src/http/lib.rs:1550. The certificate's Authority Key Identifier carries the optional issuer/serial form, and that issuer-and-serial pair does not locate the actual issuer certificate in the chain. JS error.code is AKID_ISSUER_SERIAL_MISMATCH with message 'authority and issuer serial number mismatch' (FetchTasklet.rs:1475).

Source

Thrown at src/http/error.rs:183

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

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Dump AKID of the leaf: openssl x509 -in leaf.pem -noout -text | grep -A2 'Authority Key Identifier' and check the serial it names
  2. Reissue the leaf (or the whole chain) so AKID and issuer serials are consistent
  3. If you control the CA tooling, prefer the keyIdentifier (SKI-hash) AKID form when creating certs
  4. Verify the rebuilt chain: openssl verify -show_chain -untrusted intermediates.pem leaf.pem

Example fix

# before
leaf(AKI serial 1A2B) + intermediate(serial 3C4D)
# after
leaf(AKI serial 1A2B) + intermediate(serial 1A2B)  # reissued/served matching serial
openssl x509 -in int.pem -noout -serial  # confirm it equals the AKID serial
Defensive patterns

Strategy: try-catch

Validate before calling

import { X509Certificate } from "node:crypto";
const leaf = new X509Certificate(await Bun.file("leaf.pem").text());
const text = await Bun.$`openssl x509 -in leaf.pem -noout -text`.text();
const akiSerial = text.match(/Authority Key Identifier:[\s\S]*?serial:([0-9A-F]+)/)?.[1];
if (akiSerial) {
  const intSerial = (await Bun.$`openssl x509 -in intermediate.pem -noout -serial`.text()).split("=")[1];
  if (akiSerial !== intSerial) throw new Error("AKID issuer/serial does not match served intermediate serial");
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: AKID written in the (rare) issuerName+serialNumber form pointing at a different certificate (different serial) than the one actually used to sign; chain assembled with a reissued/serial-changed intermediate while the leaf's AKID serial points at the previous one.

Common situations: Private CAs that emit the issuer/serial AKID variant, CA certificate reissue (new serial, same key and name) without reissuing leafs, hand-built chains from mixed issuance generations.

Related errors


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