astrid-runtime/astrid · error

signed Distro.lock entry '{}' does not match Distro.toml

Error message

signed Distro.lock entry '{}' does not match Distro.toml

What it means

After verifying identity, validate_signed_member_sets checks each capsule entry in the Distro.lock against the capsule declared in the signed Distro.toml. If the lock's source URL or version for a capsule differs from the signed manifest, it bails naming the capsule — the lock would otherwise silently redirect an install to a different artifact than the signed one. A missing/empty hash is separately rejected by the ensure! right after.

Source

Thrown at crates/astrid-cli/src/commands/init_signed_source.rs:361

        .map(|capsule| (capsule.name.as_str(), capsule))
        .collect();
    anyhow::ensure!(
        declared.len() == manifest.capsules.len() && lock.capsules.len() == declared.len(),
        "signed Distro.lock members do not match Distro.toml declarations"
    );
    for capsule in &lock.capsules {
        let declared_capsule = declared
            .get(capsule.name.as_str())
            .copied()
            .ok_or_else(|| {
                anyhow::anyhow!(
                    "signed Distro.lock contains undeclared capsule '{}'",
                    capsule.name
                )
            })?;
        if capsule.source != declared_capsule.source || capsule.version != declared_capsule.version
        {
            bail!(
                "signed Distro.lock entry '{}' does not match Distro.toml",
                capsule.name
            );
        }
        anyhow::ensure!(
            !capsule.hash.is_empty(),
            "signed Distro.lock entry '{}' has no capsule hash",
            capsule.name
        );
    }
    Ok(())
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Regenerate Distro.lock from the current signed Distro.toml so capsule source/version entries match the signed values.
  2. If you need the older capsule version, fetch the signed Distro.toml revision that declares that version instead.
  3. Stop hand-editing Distro.lock capsule entries; restore the file from version control and re-lock.
  4. Ask the distro maintainer to re-sign an updated Distro.toml if the change is intentional on your side (e.g. you need a mirror URL).

Example fix

// before (Distro.lock capsule entry)
[[capsules]]
name = "foo"
version = "1.0.0"
source = "https://old.example.com/foo-1.0.0.capsule"
// after (matches signed Distro.toml)
[[capsules]]
name = "foo"
version = "1.1.0"
source = "https://example.com/distros/mydistro/v1.3/foo-1.1.0.capsule"
Defensive patterns

Strategy: validation

Validate before calling

for capsule in &lock.capsules {
    if let Some(declared) = manifest.capsules.iter().find(|c| c.name == capsule.name) {
        if capsule.source != declared.source || capsule.version != declared.version {
            eprintln!("capsule {} drifted: lock={}:{} signed={}:{}",
                capsule.name, capsule.version, capsule.source, declared.version, declared.source);
        }
    }
}

Try / catch

match verify_signed_manifest(&client, &url, &manifest_hash, &lock, accept_new_key).await {
    Err(e) if e.to_string().contains("does not match Distro.toml") => {
        let capsule = e.to_string().split('\'').nth(1).unwrap_or("?");
        eprintln!("Capsule '{capsule}' differs between lock and signed manifest; run the lock workflow to re-pin it");
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: verify_signed_manifest -> validate_signed_member_sets: for a capsule in the lock, capsule.source != declared_capsule.source or capsule.version != declared_capsule.version. Happens when the lock pins an older/newer capsule version or a different source URL than what the current signed Distro.toml declares.

Common situations: Upstream bumped a capsule's version or moved its source in Distro.toml without the user re-locking; user hand-edited a capsule entry in Distro.lock; lock generated from a different signed manifest revision; dependency overridden to a mirror URL not in the signed manifest.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/c25c51e21dc5ed08. Report an issue: GitHub.