astrid-runtime/astrid · error
unexpected capsule metadata response: {other:?}
Error message
unexpected capsule metadata response: {other:?} What it means
When the kernel replies to GetCapsuleMetadata with a response that is neither CapsuleMetadata nor Error, the CLI treats it as a protocol violation and bails with a debug dump of the unexpected variant. This indicates the kernel/CLI speak different protocol versions or the response was routed incorrectly.
Source
Thrown at crates/astrid-cli/src/commands/init_grant.rs:305
/// Reuse a fresh lock only when its installed state still verifies. A current
/// distro id/version with stale or incomplete install provenance falls through
/// to the normal checked install path so init can regenerate the lock.
pub(super) async fn validated_grant_set_for_reuse(
target: &PrincipalId,
locked: &[super::LockedCapsule],
) -> Option<Vec<String>> {
if target != &crate::principal::current() {
return None;
}
let result = async {
let mut client = crate::socket_client::connect_kernel_for_workspace(None).await?;
let entries = match client
.request(astrid_core::kernel_api::KernelRequest::GetCapsuleMetadata)
.await?
{
astrid_core::kernel_api::KernelResponse::CapsuleMetadata(entries) => entries,
astrid_core::kernel_api::KernelResponse::Error(message) => bail!(message),
other => bail!("unexpected capsule metadata response: {other:?}"),
};
let mut installed = Vec::with_capacity(locked.len());
for capsule in locked {
let expected = CapsuleId::new(capsule.name.clone())?;
let entry = entries
.iter()
.find(|entry| entry.name == capsule.name)
.ok_or_else(|| {
anyhow::anyhow!(
"Distro.lock capsule '{}' is absent from the daemon registry",
capsule.name
)
})?;
if !capsule.version.is_empty() && entry.version != capsule.version {
bail!(
"Distro.lock capsule '{}' expects version {}, but the daemon registry reports {}",
capsule.name,
capsule.version,View on GitHub (pinned to affd8760f4)
Solutions
- Upgrade (or align) the CLI and kernel so GetCapsuleMetadata returns CapsuleMetadata.
- Restart the kernel process and retry.
- Inspect the {other:?} debug output to identify which variant was returned and trace why.
- Report/patch the kernel handler if a new response type must be supported by the CLI.
Defensive patterns
Strategy: type-guard
Validate before calling
// pre-flight protocol check
match client.request(KernelRequest::Ping).await? {
KernelResponse::Pong => {},
other => eprintln!("kernel protocol mismatch: {other:?}"),
} Type guard
fn is_capsule_metadata(r: &KernelResponse) -> bool {
matches!(r, KernelResponse::CapsuleMetadata(_))
} Try / catch
match request_metadata(&mut client).await {
Ok(entries) => Ok(entries),
Err(e) if e.to_string().contains("unexpected capsule metadata response") => {
eprintln!("kernel/CLI version mismatch: {e}");
Err(e)
}
Err(e) => Err(e),
} Prevention
- Match CLI and kernel versions during upgrades.
- Add a protocol/version handshake before API calls.
- Cover all KernelResponse variants in tests.
- Log unexpected variants verbatim for bug reports.
When it happens
Trigger: client.request(KernelRequest::GetCapsuleMetadata) resolves to some KernelResponse variant other than CapsuleMetadata or Error.
Common situations: Mismatched CLI and kernel versions where the kernel maps the request to a different response type; a kernel bug returning a generic/empty response for this request; middleware or proxy altering the response.
Related errors
- unexpected response from kernel: {other:?}
- unexpected response from kernel: {body:?}
- unexpected response from kernel: {other:?}
- registered FUSE service returned an incompatible status resp
- FUSE service returned an incompatible unmount response
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/6ab5c8ecb8001a2c.
Report an issue: GitHub.