{"record":{"id":"cefdf643f0e56f31","repo":"oven-sh/bun","slug":"akid-skid-mismatch","errorCode":"AKID_SKID_MISMATCH","errorMessage":"AKID_SKID_MISMATCH","messagePattern":"AKID_SKID_MISMATCH","errorType":"error_code","errorClass":"CertError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":181,"sourceCode":"    #[error(\"UNABLE_TO_VERIFY_LEAF_SIGNATURE\")]\n    UNABLE_TO_VERIFY_LEAF_SIGNATURE,\n    #[error(\"CERT_CHAIN_TOO_LONG\")]\n    CERT_CHAIN_TOO_LONG,\n    #[error(\"CERT_REVOKED\")]\n    CERT_REVOKED,\n    #[error(\"INVALID_CA\")]\n    INVALID_CA,\n    #[error(\"PATH_LENGTH_EXCEEDED\")]\n    PATH_LENGTH_EXCEEDED,\n    #[error(\"INVALID_PURPOSE\")]\n    INVALID_PURPOSE,\n    #[error(\"CERT_UNTRUSTED\")]\n    CERT_UNTRUSTED,\n    #[error(\"CERT_REJECTED\")]\n    CERT_REJECTED,\n    #[error(\"SUBJECT_ISSUER_MISMATCH\")]\n    SUBJECT_ISSUER_MISMATCH,\n    #[error(\"AKID_SKID_MISMATCH\")]\n    AKID_SKID_MISMATCH,\n    #[error(\"AKID_ISSUER_SERIAL_MISMATCH\")]\n    AKID_ISSUER_SERIAL_MISMATCH,\n    #[error(\"KEYUSAGE_NO_CERTSIGN\")]\n    KEYUSAGE_NO_CERTSIGN,\n    #[error(\"UNABLE_TO_GET_CRL_ISSUER\")]\n    UNABLE_TO_GET_CRL_ISSUER,\n    #[error(\"UNHANDLED_CRITICAL_EXTENSION\")]\n    UNHANDLED_CRITICAL_EXTENSION,\n    #[error(\"KEYUSAGE_NO_CRL_SIGN\")]\n    KEYUSAGE_NO_CRL_SIGN,\n    #[error(\"UNHANDLED_CRITICAL_CRL_EXTENSION\")]\n    UNHANDLED_CRITICAL_CRL_EXTENSION,\n    #[error(\"INVALID_NON_CA\")]\n    INVALID_NON_CA,\n    #[error(\"PROXY_PATH_LENGTH_EXCEEDED\")]\n    PROXY_PATH_LENGTH_EXCEEDED,\n    #[error(\"KEYUSAGE_NO_DIGITAL_SIGNATURE\")]","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L163-L199","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Compare identifiers: leaf AKI (openssl x509 -noout -text | grep -A1 'Authority Key') vs intermediate SKI — must match","Download the CURRENT intermediate from the CA's AIA URL embedded in the leaf and rebuild fullchain.pem","If you control the PKI and re-keyed the CA, reissue leafs or serve both old and new chains during migration","Clear any pinned intermediate from the client side (tls: { ca }) and let chain building use the served path"],"exampleFix":"# before\nleaf(issued by new-key-int) + old-key-int.pem\n# after\nleaf.pem + new-key-int.pem\n# follow the leaf's AIA pointer to fetch the matching intermediate\nopenssl x509 -in leaf.pem -noout -text | grep -A1 'Authority Information Access'","handlingStrategy":"validation","validationCode":"import { X509Certificate } from \"node:crypto\";\nconst leaf = new X509Certificate(await Bun.file(\"leaf.pem\").text());\nconst int = new X509Certificate(await Bun.file(\"intermediate.pem\").text());\nconst leafAki = leaf.toString().match(/Signature Algorithm|X509v3 Authority Key Identifier:\\s*\\n\\s*([0-9A-F:]+)/)?.[1];\nconst intSki = int.toString().match(/X509v3 Subject Key Identifier:\\s*\\n\\s*([0-9A-F:]+)/)?.[1];\nif (leafAki && intSki && leafAki.replace(/:/g, \"\") !== intSki.replace(/:/g, \"\")) {\n  throw new Error(\"leaf AKI != intermediate SKI — wrong (re-keyed?) intermediate bundled\");\n}","typeGuard":"function isAkidSkidMismatch(e: unknown): e is Error & { code: \"AKID_SKID_MISMATCH\" } {\n  return e instanceof Error && (e as any).code === \"AKID_SKID_MISMATCH\";\n}","tryCatchPattern":"try { await fetch(url); } catch (e) { if (isAkidSkidMismatch(e)) { refetchIntermediateFromAIA(new URL(url).host); throw e; } throw e; }","preventionTips":["Follow the leaf's AIA URL to fetch the current intermediate instead of pinning old files","Rebuild and redeploy chains after CA re-key events","Compare AKI/SKI pairs in your cert-lint step"],"tags":["tls","certificate","pki","rekey","chain"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}