Skip to content

Fix Timing ​

When a fix reached each supported stable NixOS channel.

This composes the containment check across the active release series and reports the result under a provenance rule. It does not discover which commit fixed a CVE; you supply that, and the response records that the attribution is yours.

Endpoint ​

GET /api/v1/cve/:id/fix-timing

Parameters ​

ParameterTypeRequiredDescription
commitstringNoThe nixpkgs commit you assert fixes this CVE, as it landed on the release branch. 7–40 hex characters.
seriesstringNoComma-separated release series, e.g. 25.11,26.05. Defaults to the current and previous stable channels.

Pass the commit as it landed on the release branch. A cherry-pick carries a different sha from the master commit it came from, so the master sha will read not_landed against a series that does carry the backport. The backports endpoint gives you the per-branch commit.

Why provenance is in the outcome ​

A commit can be attributed to a CVE three ways: somebody recorded it (first-party), you supplied it (caller) or it was found by searching pull requests and tracker comments for the CVE id. The third is a guess. nixpkgs merges plenty of pull requests that mention a CVE without fixing it, so a guess that reached a published channel is still a guess.

Rather than report a date and leave the trust question to a field you might ignore, the trust is built into the outcome:

  • landed is reachable only from first-party or caller.
  • An inferred commit reaches at most referenced_fix_landed, whose text says a merged pull request referencing this CVE reached the channel. It never says fixed, because nothing established that.

A client that ignores provenance entirely still cannot report a fix that was never established.

Outcomes ​

OutcomeMeaning
landedThe commit you supplied is contained in a published channel release. evidence.channelRelease carries the release and its publication date.
referenced_fix_landedA merged pull request referencing this CVE reached the channel. Weaker than landed, and not a fix claim.
not_landedThe commit is in no published release of that series yet.
no_trusted_fix_commitNo commit was attributed to this CVE with acceptable provenance. An absence of evidence, not evidence that the channel is unfixed.
commit_unknownGitHub has no such commit in NixOS/nixpkgs. Usually a typo or a sha from a fork.
series_unknownNo channel history exists for that series.
release_history_unresolvableThe published history for that series names a revision GitHub cannot resolve, so containment could not be computed. A property of the channel history rather than an outage: retrying will not change it, and your commit is fine.
upstream_unavailableThe check could not run; source names which upstream failed. Retry. Distinct from no_trusted_fix_commit, which means the check ran.

Without a commit, every series answers no_trusted_fix_commit. That is the ordinary response, not a fault: this version has no first-party store of nixpkgs fix commits, so coverage depends on what you bring.

Example ​

bash
curl "https://api.vulnpatch.dev/api/v1/cve/CVE-2025-27151/fix-timing?commit=33136d0e&series=25.11"
json
{
  "success": true,
  "data": {
    "cveId": "CVE-2025-27151",
    "commit": "33136d0e",
    "provenance": "caller",
    "stable": {
      "25.11": {
        "outcome": "landed",
        "evidence": {
          "commit": "33136d0e",
          "provenance": "caller",
          "channelRelease": {
            "release": "nixos-25.11.6820.c581273b8d5b",
            "revision": "c581273b8d5b",
            "publishedAt": "2026-03-03T05:18:16.000Z"
          }
        },
        "note": null
      }
    },
    "unstable": {
      "outcome": "no_version_index",
      "window": null,
      "note": "Timing on nixos-unstable is a window between the last revision carrying the vulnerable version and the first carrying the fixed one..."
    },
    "candidates": []
  }
}

The unstable channel ​

nixos-unstable has no releases for a commit to be contained in, so timing there is a window: the last revision carrying the vulnerable version, and the first carrying the fixed one. That needs an index of package versions across revisions, which this API does not have.

The outcome is therefore no_version_index. It is deliberately notpackage_not_indexed, which would assert that an index was searched and your package was absent from it. No index was searched. No window is offered rather than a date that would be a guess.

Errors ​

StatusCause
400Malformed CVE id, commit sha or series.
502The active channel list could not be read, so there is no set of series to answer for.
429Rate limited.