A Rust crate declares its license with the license field, an SPDX 2.3 expression such as MIT OR Apache-2.0, or with license-file, a path to a custom license text. crates.io requires one of the two. OR means you choose, AND means you must satisfy both, and WITH adds a named exception.
The two fields
The Cargo reference says the license field is interpreted by crates.io as an SPDX 2.3 expression, with names drawn from the SPDX list. The older slash separator, as in MIT/Apache-2.0, still works but is deprecated.
The license-file field points to a file relative to Cargo.toml. Use it for a nonstandard license. Cargo always includes that file when packaging, even if include or exclude rules would otherwise drop it.
Reading the operators
| Expression | Meaning | Record this |
|---|---|---|
| MIT OR Apache-2.0 | Pick one | The one you rely on |
| LGPL-2.1-only AND MIT AND BSD-2-Clause | Meet all three | Obligations of each |
| GPL-2.0-or-later WITH Bison-exception-2.2 | GPL plus a special exception | The exception text applies |
| Only license-file set | Custom terms | Manual review |
The dual MIT OR Apache-2.0 pattern is very common in the Rust ecosystem, which makes crate audits easier than in some other ecosystems. It still deserves a recorded choice, because Apache-2.0 brings a patent grant and notice rules that MIT does not.
A short audit routine
- List every crate in Cargo.lock, including transitive ones.
- Read the license value for the exact version in the lockfile.
- Parse expressions rather than matching strings, so AND and OR are handled correctly.
- Route license-file crates and unrecognized identifiers to manual review.
- Check again when the lockfile changes, since a new version can change terms.
Statically linked means shipped
Rust links dependencies into the binary you ship. If you distribute that binary, the notice and source obligations of every linked crate can apply. If you only run it on your own servers, the picture is different. See internal use versus distribution for how that line works.
One more habit helps with Rust: check build scripts and bundled native code. A crate that wraps a C library can carry that library's license inside its source tree, separate from the crate's own field. When a crate bundles code, read its license files as well as its manifest.
Safeguard scans dependencies and builds SBOMs from lockfiles, and you can run a free scan to see your inventory.
Quick check
What if a crate has no license field?
crates.io requires license or license-file, so a published crate should have one. If metadata is missing locally, treat the license as unknown and read the repository.
Is MIT/Apache-2.0 the same as MIT OR Apache-2.0?
The slash form is a deprecated older spelling that tools generally treat as OR. Prefer parsing the modern form.
Sources
- The Cargo Book, manifest, license and license-file: https://doc.rust-lang.org/cargo/reference/manifest.html#the-license-and-license-file-fields
- Apache License 2.0 text: https://www.apache.org/licenses/LICENSE-2.0.txt
Last reviewed: 19 October 2026.