jdx/mise · error

the stamp list from {host} for {project} has sequence {seque

Error message

the stamp list from {host} for {project} has sequence {sequence}, below the {last} already accepted; refusing what may be a rollback

What it means

Stamp-list sequences must be monotonically non-decreasing per (host, project). If a freshly fetched stamp list carries a sequence below the one already accepted, mise throws rather than risk applying a rolled-back (possibly malicious) list.

Source

Thrown at src/packslip_stamps.rs:259

        bail!(
            "{host} published a stamp list for {project} before (sequence {last}) but now answers 404 at {url}; refusing to treat that as no list, since it would drop the yanks that list carried"
        );
    }
    Ok(())
}

fn check_sequence_in(
    dir: &Path,
    host: &str,
    project: &str,
    list: &ReleaseListStatement,
) -> Result<()> {
    let mut state = read_state(dir, host)?;
    let sequence = list.predicate.sequence;
    if let Some(&last) = state.sequences.get(project)
        && sequence < last
    {
        bail!(
            "the stamp list from {host} for {project} has sequence {sequence}, below the {last} already accepted; refusing what may be a rollback"
        );
    }
    if state.sequences.get(project) != Some(&sequence) {
        state.sequences.insert(project.to_string(), sequence);
        write_state(dir, host, &state)?;
    }
    Ok(())
}

/// Fetch and verify every trusted host's list for a project. `None` when
/// no stampers are configured or the tool trusts its vendor alone. A host
/// that has no list for the project stamps nothing; one whose list fails
/// to verify is an error, since silently ignoring it would let a broken
/// host widen what another admits.
pub(crate) async fn fetch(project: &str, opts: &ToolVersionOptions) -> Result<Option<Stamps>> {
    if trusts_vendor(opts) {
        return Ok(None);

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Ensure the host publishes a stamp list with sequence >= the previously accepted one
  2. Refresh from the authoritative host that issued the higher sequence
  3. Clear the per-host stamp state only if the rollback is intentionally trusted
  4. Wait for the host to publish a new higher-sequence list

Example fix

// before: pinning to a stale mirror
MISE_PACKSLIP_STAMP_MIRROR=https://stale.example.com/ mise install aqua:org/tool
// after: use the authoritative host
mise install aqua:org/tool
Defensive patterns

Strategy: validation

Validate before calling

let state = read_stamp_state(host)?;
if let Some(last) = state.sequences.get(project) {
    let seq = peek_list_sequence(host, project)?;
    if seq < *last { eprintln!("stamp rollback {last} -> {seq}; refresh from authoritative host"); }
}

Try / catch

match result {
    Err(e) if e.to_string().contains("refusing what may be a rollback") => refresh_from_authoritative_host(host, project)?,
    other => other?,
}

Prevention

When it happens

Trigger: check_sequence_in is called with a verified stamp list whose predicate.sequence is lower than the sequence stored in the per-host state file for that project.

Common situations: A host rolled back or re-keyed its stamp lists; requests hitting a stale mirror/CDN edge; state previously synced from a newer mirror; intentional host-side reset of sequences.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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