astrid-runtime/astrid · error
signed metadata target digest is invalid
Error message
signed metadata target digest is invalid
What it means
Each target must carry both a blake3 and a sha256 digest, and `is_lower_hex_64` verifies each is exactly 64 lowercase hexadecimal characters. This error means at least one digest field is malformed — wrong length, uppercase hex, a `sha256:...` prefix, or a non-hex character — so it cannot be a valid 256-bit digest for download verification.
Source
Thrown at crates/astrid-cli/src/commands/update_channel.rs:364
let mut seen = HashSet::new();
for target in targets {
ensure!(
expected_targets.contains(&target.triple.as_str())
&& seen.insert(target.triple.as_str()),
"{label} target set is invalid"
);
let expected_asset = format!("astrid-{version}-{}.tar.gz", target.triple);
ensure!(
target.asset == expected_asset
&& target.sigstore_bundle == format!("{expected_asset}.sigstore.json"),
"signed metadata asset identity is invalid for {}",
target.triple
);
ensure!(
target.size > 0,
"signed metadata target size must be positive"
);
ensure!(
is_lower_hex_64(&target.blake3) && is_lower_hex_64(&target.sha256),
"signed metadata target digest is invalid"
);
}
ensure!(
seen.len() == expected_targets.len(),
"{label} target set is incomplete"
);
Ok(())
}
fn validate_targets(targets: &[TargetMetadata], version: &str) -> anyhow::Result<()> {
validate_targets_for(targets, TARGETS, version, "signed metadata")
}
fn musl_metadata_asset(version: &str) -> String {
format!("astrid-{version}-musl-release.toml")
}View on GitHub (pinned to affd8760f4)
Solutions
- Replace the digest with the bare 64-character lowercase hex hash of the artifact (`sha256sum` / `b3sum` output without any prefix).
- Fix the metadata generator to emit lowercase hex encoding for both digests and re-sign.
- Regenerate the signed metadata from the actual artifacts rather than pasting hashes by hand.
- Add a pre-publish lint that regex-checks `^[0-9a-f]{64}$` for both digest fields.
Example fix
// before "sha256": "sha256:AB12CD34..." // prefixed + uppercase // after "sha256": "ab12cd34..." // 64 lowercase hex chars
Defensive patterns
Strategy: validation
Validate before calling
// shell: emit bare lowercase hex digests
SHA256=$(sha256sum "$ASSET" | cut -d' ' -f1)
BLAKE3=$(b3sum "$ASSET" | cut -d' ' -f1)
[[ "$SHA256" =~ ^[0-9a-f]{64}$ && "$BLAKE3" =~ ^[0-9a-f]{64}$ ]] || exit 1 Type guard
null
Try / catch
null
Prevention
- Strip any `algorithm:` prefix from hashing tool output before embedding digests.
- Always lowercase hex-encode digests; never paste base64 or uppercase output.
- Compute digests from the final artifact bytes at publish time.
- Regex-check `^[0-9a-f]{64}$` on both fields in CI before signing.
When it happens
Trigger: `validate_targets` / `verify_release_extension` finding a target where `blake3` or `sha256` is not 64 lowercase hex chars — e.g. `"sha256": "ABCDEF..."` (uppercase), a prefixed digest (`sha256:ab12...`), a truncated hash, or an empty string.
Common situations: Digest fields copied with a `sha256:<hex>` prefix from `sha256sum` tooling output; uppercase hex from a different hashing tool; placeholders left in hand-edited metadata; a generator emitting base64 digests instead of hex.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- {label} target set is invalid
- signed metadata asset identity is invalid for {}
- signed metadata target size must be positive
- {label} target set is incomplete
- signed channel has no target '{triple}'
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c98fd9aa0d0e2820.
Report an issue: GitHub.