The first line of the daily EPSS file is a comment that names the model version and the score date. Cite both, along with the number of rows and your fetch date. Without them, an EPSS figure cannot be reproduced, because scores are recomputed every day.
Read the first line before the data
When the author downloaded the current file on 19 October 2026, its first line read:
#model_version:v2026.06.15,score_date:2026-10-18T12:03:10Z
cve,epss,percentile
CVE-1999-0001,0.04753,0.91771
Line one is a comment, so a CSV reader that does not skip it will treat it as the header and misname every column. Skip it explicitly, then read the real header on line two. The file had 390,807 CVE rows below that.
What each part means
FIRST describes EPSS as a model that estimates the probability that a published CVE will be exploited in the wild in the next 30 days, with a probability between 0 and 1 and a percentile published for every CVE every day.
| Piece | What it tells you |
|---|---|
| model_version | The model that produced these scores. A change here can shift many scores at once |
| score_date | The timestamp of the scoring run, in UTC |
| epss | The probability for that CVE on that date |
| percentile | The rank of that probability among all scored CVEs on that date |
In the fetch above the model version was dated 15 June 2026, while the scores were from 18 October 2026. Those are two different dates and you need both.
A citation line
Source: FIRST EPSS daily scores, model v2026.06.15, score date 2026-10-18T12:03:10Z, 390,807 rows, fetched 19 October 2026.
Add the fetch date because the "current" URL changes every day and does not keep yesterday's file. If you need a past date, FIRST publishes history through its data channels; verify the method on its site before relying on it, and see how to see an EPSS score on a past date.
Probability or percentile
FIRST's own guidance is that when you communicate a single EPSS score, it should be the probability, and where possible you should show both, for example "15.3% (92nd)". If your post uses percentile, say so, because a percentile moves when the set of CVEs it ranks changes. More on that in EPSS probability versus percentile.
What to avoid
- Do not write "the EPSS score" without a date. Scores change.
- Do not compare numbers from files with different model versions as if they were one series. See why a score history jumps.
- Do not describe a probability as a prediction for a specific host. It is a global estimate for a CVE.
A worked example of reading the file
Read the file in three steps and check each against what you expect.
- Read the first line. It starts with a hash and holds two comma separated pairs: model_version and score_date. In the 19 October 2026 download these were v2026.06.15 and 2026-10-18T12:03:10Z.
- Read the second line. It is the column header: cve, epss, percentile.
- Count the remaining rows. The file had 390,807.
Then spot check a known row. The first data row was CVE-1999-0001 with an epss of 0.04753 and a percentile of 0.91771. In that row the percentile is much higher than the probability looks, which is typical, since most CVEs have very small probabilities and a percentile ranks against all of them. FIRST's article on probability and percentile makes the same point: because the base rate of exploitation is low, a probability can seem smaller than its real significance.
A safe loader
import csv, gzip
with gzip.open("epss.csv.gz", "rt") as f:
meta = f.readline().strip()
rows = list(csv.DictReader(f))
print(meta, len(rows))
Reading the first line separately lets you store the metadata and keeps the CSV reader from treating the comment as the header. Save the meta string in your manifest. If a later file has a different model version, your code can warn you before you compare the two.
Why the model version belongs in every comparison
When the model version changes, scores can move for reasons unrelated to any change in the real world. Comparing yesterday's file to today's across a model change mixes two effects: the world changed and the model changed. If you chart a score over time, mark the dates where the version changed. See why a score history jumps.
| What you compare | What to check first |
|---|---|
| Two dates, same model version | Differences reflect new data |
| Two dates, different versions | Differences mix model and data changes |
| EPSS and KEV | Dates of both snapshots |
| EPSS across vendors | Whether the CVE sets match |
Citing without overclaiming
A good citation says what the number is, not what it predicts. "EPSS probability 0.04753 for CVE-1999-0001 on 2026-10-18" is a statement about a score. "This flaw has a 4.7 percent chance of being attacked at your company" is a different claim that the data does not support. FIRST describes EPSS as an estimate of exploitation in the wild in the next 30 days for a published CVE, not a measure of a specific environment.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how exploitation evidence changes how you read a finding, then compare that with what a probability can and cannot tell you.
Quick check
Do I need the model version if I cite the date?
Yes. The date says when scores were produced. The model version says which model produced them.
Why does my CSV reader show odd column names?
The first line is a comment. Skip it, or pass the reader an option to ignore lines starting with a hash.
Can I trust the file name "current" to stay the same?
The name stays but the contents change daily. That is why you record the score date, the row count and your fetch time.
Sources
- EPSS daily scores file, https://epss.empiricalsecurity.com/epss_scores-current.csv.gz (fetched 19 October 2026; header and row count read by the author).
- FIRST, EPSS overview, https://www.first.org/epss/ (fetched 19 October 2026).
- FIRST, Probability and percentile in EPSS, https://www.first.org/epss/articles/prob_percentile_bins (fetched 19 October 2026).
Last reviewed: 19 October 2026.