jdx/mise · error

mise.lock says signed , but this release is signed by …

Error message

mise.lock says {} signed {}, but this release is signed by {signer}; remove the entry from mise.lock to accept the new signer

What it means

mise.lock records which signer produced a release. During install, if any platform's lock entry names a different signer than the signer of the release currently being verified, mise fails closed: a signer change could be legitimate (key rotation) or a supply-chain attack, so the user must explicitly delete the lock entry to accept the new signer.

Solutions

  1. Verify the new signer is legitimate (check the project's announcements/key rotation docs)
  2. Remove the signer entry for the tool from mise.lock (`mise lock` refresh or edit the file) and re-run install
  3. Pin to the previous version signed by the known-good signer
  4. Audit the new release (artifact digests, provenance) before accepting

Example fix

// before: mise.lock
[tools.foo.1.2.3]
signer = "old-signer-identity"
// after: remove the entry so the new signer is accepted, then re-install
mise lock --refresh foo && mise install foo
Defensive patterns

Strategy: validation

Validate before calling

# Inspect the locked signer before upgrading
mise lock ls 2>/dev/null || jq '.tools.foo' mise.lock

Prevention

When it happens

Trigger: install_payload iterates tv.lock_platforms and finds info.signer set and differing from the release's signer — typically after a project rotates signing keys or changes signing infrastructure.

Common situations: Upstream project rotated its sigstore key; tool moved from one signing CI to another; mise.lock committed long ago now conflicts with a new release; attacker-substituted release attempts to swap signers.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/07fbc31cbe4e24d3. Report an issue: GitHub.

Appendix: source

Thrown at src/backend/packslip.rs:1325

            key_id: &verified.key_id,
            issuer: verified.issuer.as_deref(),
            attested_by: &attested_by,
            provenance: verified.provenance_linked,
            logged: verified.logged_at.is_some(),
        };
        packslip_pins::check(&project, observed)?;
        let signer = format!(
            "{scheme}:{}",
            packslip_pins::signer_of(&scheme, &verified.key_id)
        );
        let platform_key = self.get_platform_key();
        // The signer describes the release, so every platform's lock entry
        // speaks for it, not only this host's.
        for info in tv.lock_platforms.values() {
            if let Some(locked) = &info.signer
                && *locked != signer
            {
                bail!(
                    "mise.lock says {} signed {}, but this release is signed by {signer}; remove the entry from mise.lock to accept the new signer",
                    locked,
                    tv.style()
                );
            }
            if info.attested_by.is_none()
                && info.signer.is_some()
                && verified.attested_by == packslip::Attestor::Repackager
            {
                bail!(
                    "mise.lock says the vendor's own packslip was accepted for {}, but this release is a repackager's; remove the entry from mise.lock to accept that",
                    tv.style()
                );
            }
        }

        // A lockfile pins the exact artifact. Without one, choose the best
        // compatible artifact for this host, including the glibc fallback.

View on GitHub (pinned to 533346cc37)