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

  1. Check whether the crate version actually declares rust-version in its Cargo.toml; if not, 'unknown' is the correct answer
  2. Badge the latest version instead of an older one that predates MSRV support
  3. If you maintain the crate, add `rust-version = "1.x"` to Cargo.toml and publish a new version
  4. 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

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


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/792db7ec0414e658. Report an issue: GitHub.