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-timingParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
commit | string | No | The nixpkgs commit you assert fixes this CVE, as it landed on the release branch. 7–40 hex characters. |
series | string | No | Comma-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:
landedis reachable only fromfirst-partyorcaller.- 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
| Outcome | Meaning |
|---|---|
landed | The commit you supplied is contained in a published channel release. evidence.channelRelease carries the release and its publication date. |
referenced_fix_landed | A merged pull request referencing this CVE reached the channel. Weaker than landed, and not a fix claim. |
not_landed | The commit is in no published release of that series yet. |
no_trusted_fix_commit | No commit was attributed to this CVE with acceptable provenance. An absence of evidence, not evidence that the channel is unfixed. |
commit_unknown | GitHub has no such commit in NixOS/nixpkgs. Usually a typo or a sha from a fork. |
series_unknown | No channel history exists for that series. |
release_history_unresolvable | The 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_unavailable | The 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
curl "https://api.vulnpatch.dev/api/v1/cve/CVE-2025-27151/fix-timing?commit=33136d0e&series=25.11"{
"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
| Status | Cause |
|---|---|
400 | Malformed CVE id, commit sha or series. |
502 | The active channel list could not be read, so there is no set of series to answer for. |
429 | Rate limited. |