{"record":{"id":"2532f2cde1da91e2","repo":"oven-sh/bun","slug":"unnested-resource","errorCode":"UNNESTED_RESOURCE","errorMessage":"UNNESTED_RESOURCE","messagePattern":"UNNESTED_RESOURCE","errorType":"error_code","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/http/error.rs","lineNumber":213,"sourceCode":"    #[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\")]\n    KEYUSAGE_NO_DIGITAL_SIGNATURE,\n    #[error(\"PROXY_CERTIFICATES_NOT_ALLOWED\")]\n    PROXY_CERTIFICATES_NOT_ALLOWED,\n    #[error(\"INVALID_EXTENSION\")]\n    INVALID_EXTENSION,\n    #[error(\"INVALID_POLICY_EXTENSION\")]\n    INVALID_POLICY_EXTENSION,\n    #[error(\"NO_EXPLICIT_POLICY\")]\n    NO_EXPLICIT_POLICY,\n    #[error(\"DIFFERENT_CRL_SCOPE\")]\n    DIFFERENT_CRL_SCOPE,\n    #[error(\"UNSUPPORTED_EXTENSION_FEATURE\")]\n    UNSUPPORTED_EXTENSION_FEATURE,\n    #[error(\"UNNESTED_RESOURCE\")]\n    UNNESTED_RESOURCE,\n    #[error(\"PERMITTED_VIOLATION\")]\n    PERMITTED_VIOLATION,\n    #[error(\"EXCLUDED_VIOLATION\")]\n    EXCLUDED_VIOLATION,\n    #[error(\"SUBTREE_MINMAX\")]\n    SUBTREE_MINMAX,\n    #[error(\"APPLICATION_VERIFICATION\")]\n    APPLICATION_VERIFICATION,\n    #[error(\"UNSUPPORTED_CONSTRAINT_TYPE\")]\n    UNSUPPORTED_CONSTRAINT_TYPE,\n    #[error(\"UNSUPPORTED_CONSTRAINT_SYNTAX\")]\n    UNSUPPORTED_CONSTRAINT_SYNTAX,\n    #[error(\"UNSUPPORTED_NAME_SYNTAX\")]\n    UNSUPPORTED_NAME_SYNTAX,\n    #[error(\"CRL_PATH_VALIDATION_ERROR\")]\n    CRL_PATH_VALIDATION_ERROR,\n    #[error(\"SUITE_B_INVALID_VERSION\")]","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/src/http/error.rs#L195-L231","documentation":"CertError::UNNESTED_RESOURCE maps BoringSSL X509_V_ERR_UNNESTED_RESOURCE (verify code 46). It is an RPKI (RFC 3779) failure: a certificate's IP-address/AS-resource extension claims resources that are not a subset of its issuer's resources. Message: \"RFC 3779 resource not subset of parent's resources\".","triggerScenarios":"Chain validation of RPKI certificates (BGP router / CA certs carrying RFC 3779 extensions) where the child asserts prefixes or ASNs beyond the parent's allocation - e.g. parent holds 10.0.0.0/8 but child claims 192.0.2.0/24.","commonSituations":"RPKI CA operators over-allocating to a child; child certs left stale after the parent's allocation shrank (e.g. after an RIR transfer); mis-typed prefixes in allocation tooling.","solutions":["Compare resources end-to-end: inspect the RFC 3779 extensions of the chain with openssl x509 -text (autonomousSystemIds / ipAddressBlocks sections)","Reissue the child certificate with resources that are a subset of the parent's","If the parent's allocation legitimately grew, reissue the parent first, then the child","For BGP speakers, re-run krill/rpkicheck-style validation after reissuance to confirm the chain nests"],"exampleFix":"# before\n# parent: AS blocks 64512-64520 ; child claims 64512-64530\n[child_resources]\nautonomousSystemIds = 64512-64530\n\n# after: subset of parent\n[child_resources]\nautonomousSystemIds = 64512-64520","handlingStrategy":"try-catch","validationCode":"// RPKI: assert child resources nest inside parent resources before deployment\nimport { execFileSync } from \"node:child_process\";\nexport function resourcesNest(childPem, parentPem) {\n  const txt = (pem) => execFileSync(\"openssl\", [\"x509\", \"-noout\", \"-text\"], { input: pem }).toString();\n  const grab = (t) => new Set((t.match(/IPv4:[\\d./]+|IPv6:[0-9a-f:/]+|AS\\d+(?:-\\d+)?/gi) ?? []).map((s) => s.toLowerCase()));\n  const child = grab(txt(childPem)), parent = grab(txt(parentPem));\n  for (const r of child) if (!parent.has(r)) return false;\n  return true;\n}","typeGuard":"export function isUnnestedResource(e): e is Error & { code: \"UNNESTED_RESOURCE\" } {\n  return e instanceof Error && (e as any).code === \"UNNESTED_RESOURCE\";\n}","tryCatchPattern":"try {\n  await fetch(rpkiEndpoint);\n} catch (e) {\n  if (e?.code === \"UNNESTED_RESOURCE\") {\n    // child cert claims IP/AS resources beyond its parent - reissue with a subset\n    alertRpkiOperators(rpkiEndpoint);\n  } else throw e;\n}","preventionTips":["Run a nesting assertion in the issuance pipeline: child resources must be a subset of the parent's","After any allocation change upstream, re-validate the whole RPKI subtree","Automate reissuance when a parent's allocation shrinks (stale child certs are the #1 cause)"],"tags":["tls","x509","rpki","rfc3779","bgp","fetch","security"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}