astrid-runtime/astrid · error
signed Distro.toml has no [distro.signing] configuration
Error message
signed Distro.toml has no [distro.signing] configuration
What it means
verify_signed_manifest requires the parsed Distro.toml to carry a `[distro.signing]` table (containing the pubkey) before it can verify the Ed25519 signature over the lock. If `manifest.distro.signing` is None the manifest cannot be authenticated, so the CLI refuses to proceed.
Solutions
- Add a `[distro.signing]` table with a `pubkey` field to the published Distro.toml (generate via `astrid keypair generate` and convert with the ed25519:<base64> wire form)
- Confirm the source actually points at the signed manifest, not an older unsigned one
- Re-check TOML section spelling and that the file parses with `signing` under `distro`
Example fix
# before [distro] id = "my-distro" # after [distro] id = "my-distro" [distro.signing] pubkey = "ed25519:<base64-public-key>"
Defensive patterns
Strategy: validation
Validate before calling
let toml = std::fs::read_to_string("Distro.toml")?;
let manifest: DistroManifest = toml::from_str(&toml)?;
if manifest.distro.signing.is_none() {
anyhow::bail!("Distro.toml is missing [distro.signing]; add it before sealing/publishing");
} Type guard
fn has_signing(m: &DistroManifest) -> bool { m.distro.signing.is_some() } Try / catch
match verify_signed_manifest(/*..*/).await {
Err(e) if e.to_string().contains("no [distro.signing]") => {
eprintln!("Published Distro.toml lacks [distro.signing]; regenerate a signed manifest");
}
r => r?,
} Prevention
- Always include [distro.signing] with pubkey in published Distro.toml
- Lint manifests for the signing table in CI before seal/publish
- Keep Distro.toml templates updated when migrating from unsigned layouts
When it happens
Trigger: fetch_signed_manifest verifies a signed Distro.toml whose `[distro.signing]` section is missing — typically because the signing table was removed, the wrong (unsigned/legacy) Distro.toml is deployed at the source, or the table name is misspelled.
Common situations: Upgrading an old distro layout to signed sources without adding `[distro.signing]`; copying a Distro.toml template that omits the signing block; a `signings`/`signing` typo in TOML.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Capsule.toml has no package.name
- Capsule.toml has no package.version
- Cargo include optional must be a boolean in
- Cargo include table must contain a string path in
- existing [security.capsule_local_egress].
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/d296121cd08f619f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/init_signed_source.rs:302
}
/// Bind exact TOML bytes into the signed lock, then verify that lock.
fn verify_signed_manifest(
home: &AstridHome,
manifest: &DistroManifest,
manifest_hash: &str,
lock: &DistroLock,
sig_hex: &str,
accept_new_key: bool,
) -> anyhow::Result<HashMap<String, String>> {
if lock.manifest_hash.as_deref() != Some(manifest_hash) {
bail!(
"signed Distro.toml does not match Distro.lock manifest_hash; refusing to resolve members"
);
}
validate_signed_member_sets(manifest, lock)?;
let signing = manifest.distro.signing.as_ref().ok_or_else(|| {
anyhow::anyhow!("signed Distro.toml has no [distro.signing] configuration")
})?;
let outcome = trust::verify_and_pin(
home,
&manifest.distro.id,
&signing.pubkey,
sig_hex,
lock,
accept_new_key,
trust::TrustPolicy::RequireExistingPin,
)?;
tracing::info!(
distro = %manifest.distro.id,
action = ?outcome.action,
"authenticated source Distro"
);
Ok(lock
.capsulesView on GitHub (pinned to affd8760f4)