badges/shields · info · NotFound
unknown
Error message
unknown
What it means
The crates.io MSRV badge service throws NotFound with prettyMessage 'unknown' in CratesMsrv.transform when the version object from the crates.io API has no `rust_version` field. `rust_version` (the Minimum Supported Rust Version) is optional metadata, so its absence means the crate version never declared an MSRV.
Source
Thrown at services/crates/crates-msrv.service.js:59
example: 'serde',
},
{
name: 'version',
example: '1.0.194',
},
),
},
},
}
static _cacheLength = 3600 // We're hitting the API more frequently than requested by upstream maintainers (see https://github.com/badges/shields/issues/11879).
static defaultBadgeData = { label: 'msrv', color: 'blue' }
static transform(response) {
const msrv = this.getVersionObj(response).rust_version
if (!msrv) {
throw new NotFound({ prettyMessage: 'unknown' })
}
return { msrv }
}
async handle({ crate, version }) {
const json = await this.fetch({ crate, version })
const { msrv } = this.constructor.transform(json)
return { message: msrv }
}
}
View on GitHub (pinned to 766fd8bc89)
Solutions
- Check whether the crate version actually declares rust-version in its Cargo.toml; if not, 'unknown' is the correct answer
- Badge the latest version instead of an older one that predates MSRV support
- If you maintain the crate, add `rust-version = "1.x"` to Cargo.toml and publish a new version
- If you need a value anyway, use another badge or compute MSRV yourself rather than the msrv badge
Example fix
// before # Cargo.toml (no MSRV) -> badge shows "unknown" // after [package] rust-version = "1.70.0"
Defensive patterns
Strategy: fallback
Validate before calling
async function hasMsrv(crate, version) {
const res = await fetch(`https://crates.io/api/v1/crates/${crate}${version ? '/' + version : ''}`)
const data = await res.json()
const v = version ? data.versions?.find(x => x.num === version) : data.versions?.[0]
return v?.rust_version != null
} Type guard
function hasMsrv(v) {
return typeof v?.rust_version === 'string' && v.rust_version.length > 0
} Try / catch
try {
msrv = await getCratesMsrvBadge(crate, version)
} catch (err) {
if (err.prettyMessage === 'unknown') {
msrv = 'MSRV not declared'
} else throw err
} Prevention
- Check the crate's Cargo.toml for rust-version before requesting the msrv badge
- Badge the latest version, which is more likely to declare an MSRV
- For your own crates, always set rust-version in [package]
- Treat 'unknown' as expected output for pre-1.56-era crates, not a bug
When it happens
Trigger: Requesting an msrv badge for a crate or version whose Cargo.toml did not declare `rust-version`, so crates.io returns no `rust_version` for that version.
Common situations: Crates published before the rust-version field existed (pre-Rust 1.56 era); crates that simply never set rust-version; querying old versions of a crate that only recently added MSRV.
Related errors
- invalid null license
- version not found
- recent downloads not supported for specific versions
- not set for this ${extensionType}
AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30).
Data as JSON: /api/errors/792db7ec0414e658.
Report an issue: GitHub.