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. 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 second and third are both, in the end, somebody's claim rather than something this service independently verified: nixpkgs merges plenty of pull requests that mention a CVE without fixing it, and a commit you name is no more confirmed to be the fix than one found by searching text.
Rather than report a date and leave the trust question to a field you might ignore, the trust is built into the outcome:
landed-- the word that reads as a confirmed fix -- is reachable only fromfirst-party, the one provenance this service itself verified.- A commit you supply (
caller) or one found by searching (inferred) both reach at mostreferenced_fix_landed. For an inferred commit the text says a merged pull request referencing this CVE reached the channel; for yours it says the commit you supplied reached the channel and that it fixes the CVE is your own attribution, not independently verified. Neither ever says fixed outright.
evidence.provenance still names who is accountable for the claim, caller included, so you can tell your own attribution from an inferred one even though both land on the same, weaker outcome.
A client that ignores provenance entirely still cannot report a fix that was never established.
Outcomes
| Outcome | Meaning |
|---|---|
landed | A first-party commit is contained in a published channel release. evidence carries the release and its publication date. Never reached from a caller-supplied commit. |
referenced_fix_landed | The commit reached the channel, but its connection to this CVE is somebody's claim (yours, if evidence is caller) rather than something this service verified. 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. |
internal_error | Containment could not be computed because of a fault in this service, not an upstream. Distinct from upstream_unavailable: retrying won't help by waiting out someone else's outage. |
no_version_index | nixos-unstable has no window: it would need an index of package versions across revisions this service does not have, so none is offered rather than a guessed date. |
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": "referenced_fix_landed",
"evidence": {
"commit": "33136d0e",
"provenance": "caller",
"channelRelease": {
"release": "nixos-25.11.6820.c581273b8d5b",
"revision": "c581273b8d5b",
"publishedAt": "2026-03-03T05:18:16.000Z"
}
},
"note": "The commit you supplied reached nixos-25.11 on 2026-03-03. That it fixes this CVE is your own attribution; this service did not independently verify it."
}
},
"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. |