jdx/mise · error
the release list expired at {}; the vendor has not published
Error message
the release list expired at {}; the vendor has not published a fresh one What it means
After cryptographically verifying the vendor's signed release list, mise additionally checks that the list is still temporally valid via `is_current`. If the list's `predicate.expires_at` timestamp has passed, the signature may be valid but the attestation is stale — the vendor must publish a fresh signed list. mise refuses to proceed with an expired list rather than trusting outdated withdrawal/version data.
Source
Thrown at src/backend/packslip.rs:517
packslip::verify(bundle, &pin.trust(), options, artifacts).map_err(|e| eyre!("{e}"))
})
}
pub(crate) fn verify_release_list(
bundle: &str,
pin: &Pin,
require_log: bool,
) -> Result<ReleaseListStatement> {
file::run_blocking(|| {
let root = packslip::sigstore::trusted_root(None).map_err(|e| eyre!("{e}"))?;
let options = packslip::Options {
require_log,
trusted_root: &root,
};
let verified = packslip::verify_release_list(bundle, &pin.trust(), options)
.map_err(|e| eyre!("{e}"))?;
if !verified.list.is_current(jiff::Timestamp::now()) {
bail!(
"the release list expired at {}; the vendor has not published a fresh one",
verified.list.predicate.expires_at
);
}
Ok(verified.list)
})
}
/// The headers a download from GitHub needs; nothing for anywhere else.
/// Listing timestamps only filter candidates. The authenticated log time
/// decides whether a selected release is old enough to install.
fn check_verified_age(
logged_at: Option<&str>,
published_at: &str,
before: Option<jiff::Timestamp>,
) -> Result<()> {
let Some(before) = before else {
return Ok(());View on GitHub (pinned to afd2eddd3a)
Solutions
- Wait for the vendor to publish a fresh signed release list, then retry `mise install`
- Refresh mirrors/cache so you fetch the latest list, or clear any cached release list
- Check the local clock (NTP sync) if expiry seems wrong; report the stale list to the vendor if they are active
Defensive patterns
Strategy: retry
Try / catch
match mise::install(tool) {
Err(e) if e.to_string().contains("release list expired") => {
schedule_retry_after_vendor_republish();
}
other => other?,
} Prevention
- Prefer actively maintained vendors that republish lists regularly
- Keep mirrors/cache fresh so you always fetch the newest list
- Keep clocks NTP-synced to avoid false expiry
- Watch vendor status pages for release-list publication outages
When it happens
Trigger: Calling `release_list`, `github_list`, or `fetch` for a packslip project when `verified.list.is_current(Timestamp::now())` returns false, i.e. the current time is past `predicate.expires_at` of the fetched release list.
Common situations: A vendor stops publishing fresh release lists (project abandoned or transparency log outage); a stale mirror or cache serves an old list; system clock skew makes the local time appear past the expiry.
Related errors
- packslip release was recorded by the {source} at {time}, aft
- packslip:{project}@{version} was withdrawn by the vendor{}
- packslip:{project}: this release {}. If the vendor announce
- must not record a pin before replacement succeeds
- packslip:{tool_name} is not a project name; use github.com/o
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/34eae939b8877374.
Report an issue: GitHub.