{"record":{"id":"1417e49b5ccb235a","repo":"astrid-runtime/astrid","slug":"capsule-id-provides-an-uplink-but-is-absent-fr","errorCode":null,"errorMessage":"capsule '{id}' provides an uplink but is absent from the operator-owned [[uplinks]] allowlist","messagePattern":"capsule '(.+?)' provides an uplink but is absent from the operator-owned \\[\\[uplinks\\]\\] allowlist","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":552,"sourceCode":"enum RuntimeResidency {\n    Principal,\n    SystemResident,\n}\n\nimpl RuntimeResidency {\n    const fn is_system(self) -> bool {\n        matches!(self, Self::SystemResident)\n    }\n}\n\nfn classify_runtime_residency(\n    manifest: &astrid_capsule_types::manifest::CapsuleManifest,\n    id: &astrid_capsule_types::CapsuleId,\n    system_allowed: bool,\n) -> Result<RuntimeResidency, anyhow::Error> {\n    let provides_uplink = !manifest.uplinks.is_empty();\n    if provides_uplink && !system_allowed {\n        anyhow::bail!(\n            \"capsule '{id}' provides an uplink but is absent from the \\\n             operator-owned [[uplinks]] allowlist\"\n        );\n    }\n    if system_allowed && (manifest.capabilities.uplink || provides_uplink) {\n        Ok(RuntimeResidency::SystemResident)\n    } else {\n        Ok(RuntimeResidency::Principal)\n    }\n}\n\nimpl Kernel {\n    async fn lock_capsule_view(\n        &self,\n        principal: &PrincipalId,\n        capsule: &CapsuleId,\n    ) -> CapsuleViewGuard {\n        let key = CapsuleViewKey {","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L534-L570","documentation":"This error means a capsule manifest declares one or more uplinks (manifest.uplinks is non-empty), but the operator has not allowed the capsule's identity in the operator-owned [[uplinks]] allowlist (system_allowed was false). The kernel refuses to grant uplink residency to capsules that are not explicitly allowlisted, because an uplink grants network/egress reach out of the sandbox. It is an operator policy gate, not a bug in the capsule itself.","triggerScenarios":"Calling the residency-resolution function (used by load_capsule / prepare_runtime_replacement paths) with a manifest whose uplinks list is non-empty while the system_allowed flag is false — i.e., the operator's [[uplinks]] allowlist does not contain this capsule's id.","commonSituations":"A developer adds an [[uplinks]] entry to their Capsule.toml but the operator never added the capsule id to the host's uplink allowlist; the allowlist exists but the capsule id string doesn't match exactly (case/typo); after a fresh environment setup where the operator allowlist was not migrated.","solutions":["Have the operator add the capsule's id to the [[uplinks]] allowlist in the operator configuration, then retry","Remove the [[uplinks]] entries from the capsule manifest if the capsule does not actually need network egress","Verify the capsule id in the allowlist matches the manifest id exactly (spelling, case)","If residency was expected to be non-system (user-resident), confirm which code path is passing system_allowed=false and whether an allowlist entry is genuinely required"],"exampleFix":"// before: operator config missing the capsule\n[[uplinks]]\nid = \"some-other-capsule\"\n\n// after: allowlist the capsule that declares uplinks\n[[uplinks]]\nid = \"your-capsule-id\"","handlingStrategy":"validation","validationCode":"if !manifest.uplinks.is_empty() && !operator_uplink_allowlist.contains(&manifest.package.id) {\n    return Err(\"capsule declares uplinks but is not on the operator [[uplinks]] allowlist\");\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"[[uplinks]] allowlist\") => {\n        // surface which allowlist entry is missing; do not retry\n    }\n    other => other?,\n}","preventionTips":["Keep the operator [[uplinks]] allowlist in version control and review changes","Before shipping, lint capsule manifests for uplinks against the target environment's allowlist","Match capsule ids in the allowlist exactly (copy from the manifest, don't retype)","Only declare uplinks in Capsule.toml when the capsule truly needs egress"],"tags":["config","policy","network","allowlist","capsule"],"backgroundTag":"permission-denied","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}