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

  1. Wait for the vendor to publish a fresh signed release list, then retry `mise install`
  2. Refresh mirrors/cache so you fetch the latest list, or clear any cached release list
  3. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/34eae939b8877374. Report an issue: GitHub.