Rust rustup

ID

rustup

Home page

https://rustup.rs

Version requirement

>= 1.28

Platforms

🐧 Linux · 🍎 macOS · 🪟 Windows

Operations

installed · outdated · install · upgrade · upgrade_all · remove

purl types

pkg:rustup

CLI name

rustup

Forced environment

RUSTUP_TERM_COLOR=never · RUSTUP_TERM_PROGRESS_WHEN=never

Issues and PRs

📦 manager: rustup

Source

meta_package_manager/managers/rustup.toml

rustup is the Rust toolchain installer (https://rustup.rs).

The packages here are toolchains, not components. rustup exposes both, and only one can be the inventory: a package is a stable-aarch64-apple-darwin or a 1.62.0-x86_64-unknown-linux-gnu, which is exactly the string toolchain install, toolchain uninstall and update all accept, so every declared operation addresses the same object. Components lose that on three counts, any one of them decisive. They are scoped to a toolchain, so clippy on stable and clippy on nightly are different installs wearing one name. They carry no version of their own, being versioned by the toolchain that holds them. And a bare component list answers for whichever toolchain is active, which would make mpm’s inventory depend on ambient state rather than on the machine.

installed therefore reports no version, which is deliberate rather than an omission: a toolchain listing carries none. --verbose appends the install path, not a version, and the only per-toolchain version rustup will produce comes from spawning that toolchain’s own rustc once per entry, which is the per-package follow-up call a definition cannot make. outdated supplies both versions where it matters, and mpm’s package model treats an installed version as optional throughout.

rustup check is what outdated runs, and its two quirks are both handled rather than worked around. It exits 100 when updates exist, which needs no declaration: mpm only counts a non-zero exit as a failure for a read-only query when stderr is also non-empty, and a successful check writes nothing there. And it appends a line for rustup’s own binary, which the pattern excludes by requiring a hyphen in the first field, a shape every toolchain triple has and the bare rustup of that line does not.

Every mutating operation forces --no-self-update. rustup otherwise replaces its own binary as a side effect of installing or updating a toolchain, on all three branches, which is not what a user asking mpm to upgrade a package expects. Two exposures stay outside that flag’s reach, both being global user state rather than per-invocation: an auto-self-update = check-only setting is consulted before the flag, and a non-empty CI disables self-update outright.

No search: rustup has no registry to search, its channel names being a fixed vocabulary. No sync and no cleanup: neither command exists. Purging the download cache happens only as a side effect of an argument-less rustup update, and cannot be invoked on its own.

No escalation. rustup installs under $RUSTUP_HOME (~/.rustup by default), has no system-wide mode, and actively refuses to run under sudo.

Caution

rustup’s output has no stability guarantee, and its maintainers say so plainly: the 1.28.0 reformatting of rustup show broke downstream parsers, and a further restyling of rustup check is proposed in rust-lang/rustup#4574. The outdated pattern below is deliberately tolerant of both the Update available : spelling of 1.28.x and the update available: of 1.29.0, so a wrapper does not break on the next rename the way mise’s did.

Note

Listing toolchains is not a read-only operation at the filesystem level: rustup writes its settings file while doing it, so installed fails on a host whose $RUSTUP_HOME is mounted read-only.

What mpm adds to rustup

mpm reaches across every manager at once, not rustup alone: mpm installed and mpm outdated cover rustup alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.

Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.

Your rustup commands, in mpm

You already know rustup: each operation maps one-to-one onto mpm, in an interface shared by every manager.

To…

With rustup

With mpm

List what’s installed

rustup toolchain list

mpm --rustup installed

List outdated packages

rustup check

mpm --rustup outdated

Install a package

rustup toolchain install --no-self-update <package_id>

mpm install pkg:rustup/<package_id>

Upgrade one package

rustup update --no-self-update <package_id>

mpm --rustup upgrade <package_id>

Upgrade everything

rustup update --no-self-update

mpm --rustup upgrade --all

Remove a package

rustup toolchain uninstall <package_id>

mpm remove pkg:rustup/<package_id>

Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.

Operations

Operation

Supported

installed

outdated

orphans

search

install

upgrade

upgrade_all

remove

sync

cleanup

doctor

Selecting and configuring rustup

Deselect rustup for a single run with --no-rustup, or persist the choice in your configuration:

[mpm]
rustup = false

The arguments and environment variables listed in the box atop this page are forced on every rustup call, so runs stay quiet, non-interactive and reproducible: the defaults you would set in CI anyway.

Keep it enabled but tune how mpm drives it with a per-manager override:

[mpm.managers.rustup]
timeout = 900

mpm config-template rustup prints every overridable attribute as a ready-to-paste block.

Recipes

A few jobs you would otherwise script around rustup, one mpm command each:

  • Snapshot and clone a machine: mpm --rustup dump rustup.toml, then mpm restore rustup.toml on the next one.

  • Export a compliance SBOM: mpm --rustup sbom (CycloneDX by default, --spdx for SPDX).

Privilege escalation

mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.

None of its operations needs root.

See privilege escalation for the full policy.

Cooldown

State of Rust rustup’s release-age gating, from the cooldown support table:

Status: ❌ None

A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:

  • Registry: Rust release channels (pkg:cargo toolchains)

  • Retraction: None published: releases are static artifacts on the project’s own distribution host, with no yank, unlist or delete surface exposed to anyone outside the Rust release team; a withdrawal is a change to the channel manifest that host serves

  • Publish date: ✅ every channel manifest carries the release date of the toolchain it describes, which rustup check reports alongside the version

With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --allow-unsupported-managers opts back in.

Version probe

The version is probed by running:

$ rustup --version
rustup 1.29.0 (28d1352db 2026-03-05)

and extracted with:

r"^rustup (?P<version>\S+)"

Reference traces

Raw native outputs captured in the bundled definition: the reference mpm’s parsers were written against. If you know Rust rustup well and a transcript below looks wrong, or a newer release changed its output format, report it.

$ rustup toolchain list
stable-x86_64-unknown-linux-gnu (active, default)
nightly-x86_64-unknown-linux-gnu
1.14-x86_64-unknown-linux-gnu
1.62.0-x86_64-unknown-linux-gnu
1.71-x86_64-unknown-linux-gnu
$ rustup check
stable-x86_64-unknown-linux-gnu - update available: 1.0.0 (hash-stable-1.0.0) -> 1.1.0 (hash-stable-1.1.0)
nightly-x86_64-unknown-linux-gnu - up to date: 1.1.0 (hash-nightly-1.1.0)

Feed any of these through mpm and the raw output becomes one uniform table, the same shape for every manager: filter it, project columns, or export it (mpm --rustup installed --output json, or csv, toml, yaml), each package carrying a purl and a version comparable across managers.

Changelog

  • 7.7.0.dev0 (unreleased)

    • Add the Rust rustup toolchain installer with installed, outdated, install, upgrade and remove support, shipped as a bundled definition. Toolchains are the packages: components are scoped to a toolchain and a bare component listing answers for whichever one is active. Every mutating call forces --no-self-update, so upgrading a toolchain no longer replaces the rustup binary as a side effect. Installed toolchains carry no version, which only outdated reports.