Skip to content
rusthacks.dev
Tooling

Pinning a Toolchain With Rust Toolchain Toml in a Project

Pin the Rust version, components and targets for a project with rust-toolchain.toml so every laptop and CI job builds the same way. Covers channel choices and the file format.

2 min read
Summarize in AI
Flat illustration for the post “Pinning a Toolchain With Rust Toolchain Toml in a Project”, composed around serde.

"It builds on my machine" is often a compiler version difference. One small file removes it. rust-toolchain.toml sits at the project root, and rustup reads it and makes sure everyone, human or CI, uses the same toolchain. This post gives the file, the choices inside it, and the interaction with other settings. It follows the resolution order in rustup explained.

Rust 1.90, rustup 1.28.

The file

rust-toolchain.tomlTOML
[toolchain]
channel = "1.90.0"
components = ["rustfmt", "clippy", "rust-src"]
targets = ["x86_64-unknown-linux-musl"]
profile = "minimal"

Run cargo --version in the folder. On first run, rustup downloads the toolchain and prints a line for each installed piece. A teammate who clones the repository gets the same version without being told.

Exact version or channel

ChoiceProsCons
"1.90.0"every build identical, upgrades are reviewed commitssomeone must bump it
"stable"always currenta new release can break the build, differently on each laptop
"nightly-2026-10-01"reproducible nightly, needed for Miri and unstable featuresmust update by hand, and some dates lack components

For an application, pin and update on a schedule with a pull request that runs CI. For a library, test on the minimum supported version, current stable and beta in CI, and keep the local file on stable. The reasoning for MSRV is in declaring MSRV.

Components and targets

Everything the project invokes should be here. A missing rustfmt fails cargo fmt for the new contributor with a message to install it; listing it avoids the round trip. rust-src is needed by rust-analyzer for std navigation and by -Zbuild-std. List only what you use, to keep CI downloads small.

Legacy format

A plain text file named rust-toolchain containing just 1.90.0 still works. Use the TOML form, because only it can carry components and targets.

Interaction with other settings

  • cargo +nightly build wins over the file.
  • RUSTUP_TOOLCHAIN wins over the file.
  • A rustup override for the directory wins over the file as well, so remove stale overrides with rustup override unset.
  • The file does not change rust-version in Cargo.toml, which states what your crate promises to support.

In CI

GitHub Actions dtolnay/rust-toolchain can read it, or just run rustup show and let it install. With the file in place, a CI step that uses cargo already picks the pinned version. Caching the toolchain directory saves a minute per run. See GitHub Actions for Rust.

Pitfalls

The file is found by searching up from the current directory, so a stray one in a parent folder or home directory can affect unrelated projects. Dev containers that bake a toolchain into the image must match it. Reference: the rustup book chapter on overrides.

Taggedrustup
Share

Keep reading

Flat illustration for the post “Incident Response for Rust Services a Short Runbook”, composed around deploy.
DevOps

Incident Response for Rust Services a Short Runbook

A one-page runbook for when a Rust service misbehaves: stabilize first, check recent changes, read the four golden signals, find the failing dependency, and use the Rust-specific evidence: panics, memory, executor stalls.

4 min read
Flat illustration for the post “Debugging Async Backtraces and Task Dumps in Tokio”, composed around async.
Tooling

Debugging Async Backtraces and Task Dumps in Tokio

A hung async service has no useful thread backtrace. Tokio task dumps capture the await stack of every task. Enable tokio_unstable and taskdump, trigger a dump from a signal or endpoint, and read where each task is parked.

4 min read

Get new posts by email

We send one email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.