SECOND MEASUREMENT SM-009

Firefox promised a list of every revoked certificate. A third of the ones revoked on day one aren’t on it, and it no longer asks anyone else

Markovian ProtocolMeasured 2026-10-02Status: sent to Mozilla 2026-10-02, response pendingDOI: 10.5281/zenodo.23123001

Since August 2025, Firefox decides whether a website’s certificate has been revoked by looking it up in a list it downloads twice a day, called CRLite, instead of asking the certificate authority. Mozilla says the list holds all revocations, and Firefox skips the online check for anything the list doesn’t cover. We pulled 1,718 fresh revocations straight from 125 certificate authorities’ own revocation lists and asked today’s Firefox filters about each one, using Mozilla’s own query code. Of the 465 we could test exactly, 427 come back revoked and 38 come back good or not covered (36 and 2). Among certificates revoked within a day of being issued, 37 of 108 pass. Every one of the 38 carries timestamps only from logs with a 24-hour merge delay, a gap Mozilla wrote up a year ago and hasn’t closed. They stay invisible until the next full filter, and the current one is dated 2 September.

The short version

Disclosure: Markovian Protocol holds no financial position in any organisation named here, was paid by no one for this work, and showed it to no one before publication except the organisation measured. How we work.

Details

A certificate authority publishes a certificate revocation list, a CRL: the serial numbers of certificates it has cancelled before they expire. CRLite is Mozilla’s way of shipping every such list to every Firefox at once. Mozilla’s servers read the CRLs of every CA Firefox trusts, compress the result into a filter about 6 MB in size, and push small updates twice a day. Firefox 142 made its answers final. The filter can only answer for certificates it knows about, and it knows a certificate through the timestamps the certificate carries from Certificate Transparency logs. When those timestamps say the filter can’t know yet, Firefox treats the certificate as not covered. For an ordinary domain-validated certificate chaining to a built-in root, Firefox then skips the online OCSP check and lets the connection through. Mozilla’s source comments say so in as many words.

What they said, what we found

Mozilla saidWe found
“CRLite is efficient enough to store all certificate revocations locally, requiring only 300KB per day of continuous updates to stay current.” (Firefox blog, 19 August 2025)1Of 465 current revocations tested with the exact certificate: 427 stored, 38 not. Revoked within 24 hours of issuance: 37 of 108 not stored, after 4 to 28 days.
The same sentence: “requiring only 300KB per day of continuous updates to stay current.”1Desktop channel, last 30 days: 61 deltas, 13.46 MB, 441 KB a day; 649 KB a day counting the 6.3 MB snapshot. Android channel: 238 KB a day. From the Remote Settings records in the exhibits.
Firefox’s verifier: when the filter doesn’t cover a certificate, “it’s reasonable to skip the synchronous OCSP request here. In effect, we’re choosing to preserve the privacy of the user at the risk of potentially allowing them to navigate to a site that is serving a revoked certificate.”2True to the code. The 38 certificates come back “Good” (36) or “NotCovered” (2); either way the connection proceeds.
Firefox on Android subscribes to a smaller “compat” channel that carries only three revocation reasons: key compromise, cessation of operation, privilege withdrawn.3On that channel 419 of the 465 revoked certificates come back good. That is by design, and it isn’t what the blog post says.

How Firefox decides

Picture a doorman with a printed guest list who used to phone the office for anyone he wasn’t sure about. Now he carries the list and has stopped phoning. The list is reprinted twice a day. The catch is how a name gets on it.

Every public certificate is logged to Certificate Transparency before it’s used, and carries two or three signed timestamps from those logs. Each log promises to publish an entry within its merge delay: 24 hours for the older logs, 60 seconds for the newer tiled ones. Mozilla’s filter says, for each log, “I have seen everything in this log up to time T”, and T is one merge delay behind what the server has actually read. Firefox checks a certificate’s timestamps against those T values. If none of the certificate’s logs has reached it yet, the filter is not consulted, and nothing else is either.

Mozilla’s John Schanck described the failure in September 2025, in the project’s issue tracker.4 A certificate that is revoked within one merge delay of being logged lands in the revoked set while the filters still count it as unknown. The twice-daily updates only carry what is newly revoked, so once the certificate is in the set, no later update mentions it again. The next full filter would include it. The current full filter is dated 2 September. Everything since has been an update.

We timed that promise ourselves. A fresh certificate submitted to every log on the Google and Apple lists that will take one today, 64 logs, was served by all of them inside their stated delay: the 43 tiled logs within 6 seconds, DigiCert’s classic logs in 10, Google’s and Sectigo’s in one to two minutes, TrustAsia’s in two and a half, and Cloudflare’s Nimbus in 46 and 61 minutes. The 24-hour figure the filter waits on is a ceiling; the logs run between twenty-four and a thousand times under it. The gap is in what the client assumes, not in what the logs do (the check).

A fix merged on 25 September 2025.5 In November a user reported Let’s Encrypt’s own revoked test site still showing as good; Schanck explained that the certificate’s embedded timestamps came from two 24-hour logs and that the problem “will more or less resolve itself once CAs start logging precertificates to static CT logs”.6 Our sample says most CAs haven’t yet: all 38 certificates that slipped through were logged only to 24-hour logs.

The count

We did not use Mozilla’s data. The revocations come from the CAs: CCADB, the shared database of browser root programs, lists 18,328 CRL files for the intermediates Firefox trusts. We fetched 2,201 of them at random and parsed 2,198 (12 per organisation, 150 extra for organisations with hundreds of shards), parsed 173,408 revocations dated between 2 and 30 days ago, and drew up to 20 per organisation: 1,718 from 125 organisations. crt.sh, the public Certificate Transparency search engine, found 1,108 of them; the rest are mostly not website certificates at all, since CAs put client and email certificates on the same CRLs. 41 had expired. That left 1,067 to query.

Firefox judges a certificate by its issuer’s key, its serial number, and its embedded log timestamps. For 465 of the 1,067, crt.sh holds the final certificate, so all three are exact and we ran Mozilla’s own rust-query-crlite on the file. For the other 602, only the precertificate is public, and the timestamps come from crt.sh’s record of which logs it saw the precertificate in. That record is incomplete for several logs, so those 602 are reported separately and left out of the headline.

Firefox desktop filter, 2 OctoberRevokedGoodNot coveredSlips through
465 with the final certificate (exact)42736238 (8.2%)
  of which revoked within 24 h of issuance7135237 of 108
  of which revoked later than 24 h356101 of 357
602 with only the precertificate (crt.sh timestamps)563534see note

Filters downloaded 2 October 2026 with rust-query-crlite --update prod: snapshot 20260902-0 plus 61 deltas, newest effective 13:01 UTC. “Not covered” in the precertificate rows is mostly crt.sh missing the certificate’s other logs, not Firefox; see what we can’t be sure of.

Firefox’s own query tool agrees with our raw-key path on 463 of 465 exact cases. The two “expired” disagreements are certificates that expired during the day of the run.

The 38 that slip through:

IssuerIssued (UTC)Revoked by CAHours betweenReason on CRLFirefox says
Hellenic Academic and Research Institutions CA2026-09-04 08:592026-09-04 09:090.2none givenGood
UniTrust2026-09-07 03:392026-09-07 13:5010.2none givenGood
UniTrust2026-09-08 09:342026-09-08 09:420.1none givenGood
DNSPod, Inc.2026-09-09 08:422026-09-09 10:011.3none givenGood
Hellenic Academic and Research Institutions CA2026-09-09 09:562026-09-09 10:170.4affiliation_changedGood
SSL Corp2026-09-10 16:022026-09-10 19:463.7supersededGood
SSL Corp2026-09-10 16:052026-09-10 19:353.5supersededGood
SSL Corp2026-09-10 16:062026-09-10 19:153.2supersededGood
SSL Corp2026-09-10 16:092026-09-10 19:263.3supersededGood
SSL Corp2026-09-10 16:122026-09-10 19:123.0supersededGood
Cybertrust Japan Co., Ltd.2026-09-11 01:372026-09-11 03:442.1supersededGood
UniTrust2026-09-11 08:412026-09-11 13:455.1none givenGood
SSL Corp2026-09-11 15:112026-09-11 20:185.1none givenGood
SSL Corp2026-09-11 15:112026-09-11 20:175.1none givenGood
PKI(Chongqing) Limited2026-09-12 13:332026-09-12 18:555.4none givenGood
PKI(Chongqing) Limited2026-09-12 13:542026-09-12 19:205.4none givenGood
PKI(Chongqing) Limited2026-09-12 14:172026-09-12 19:205.0none givenGood
UniTrust2026-09-13 01:252026-09-13 03:302.1none givenGood
Shanghai Huandu Info Tech Co. Ltd.2026-09-14 03:122026-09-14 08:305.3none givenGood
UniTrust2026-09-14 07:002026-09-14 09:152.2none givenGood
NAVER Cloud Trust Services Corp.2026-09-17 00:002026-09-17 11:3411.6affiliation_changedGood
Actalis S.p.A.2026-09-17 07:102026-09-18 12:5529.7none givenGood
Hellenic Academic and Research Institutions CA2026-09-17 08:052026-09-17 08:160.2none givenGood
Google Trust Services2026-09-19 02:362026-09-19 08:225.8cessation_of_operationNotCovered
UniTrust2026-09-20 00:502026-09-20 03:102.3none givenGood
Shanghai Huandu Info Tech Co. Ltd.2026-09-21 02:132026-09-21 02:430.5none givenGood
NETLOCK Kft.2026-09-21 08:252026-09-21 08:310.1supersededGood
DigiCert, Inc2026-09-22 00:002026-09-22 09:049.1supersededGood
DigiCert, Inc2026-09-22 00:002026-09-22 09:049.1supersededGood
DigiCert, Inc.2026-09-22 00:002026-09-22 09:049.1supersededNotCovered
UniTrust2026-09-22 02:362026-09-22 03:551.3none givenGood
UniTrust2026-09-22 16:362026-09-22 16:400.1none givenGood
UniTrust2026-09-22 16:382026-09-22 16:400.0none givenGood
Gandi SAS2026-09-23 00:002026-09-23 10:1310.2none givenGood
Henan Fierce Fire Network Technology Co., Ltd.2026-09-25 01:272026-09-25 02:130.8none givenGood
Shanghai Huandu Info Tech Co. Ltd.2026-09-28 02:202026-09-28 09:056.7none givenGood
GeoSSL, Inc.2026-09-28 08:102026-09-28 08:240.2none givenGood
Henan Fierce Fire Network Technology Co., Ltd.2026-09-28 10:422026-09-28 11:190.6none givenGood

All 38 carry timestamps only from logs with a 24-hour merge delay (Argon, Xenon, Tiger, Elephant, Sphinx, Wyvern, Nimbus, HETU, TrustAsia log2026a). None of the 11 key-compromise revocations in the 465 was missed; none of the 21 in the other 602 either.

How this ends

It ends when Firefox’s filter stops waiting a full merge delay on the classic logs, or when the certificates that matter are logged somewhere it reads promptly. The daily recheck re-asks each day’s filter about the same revoked certificates; the number still coming back “good” is the ending, counted down.

The evidence

Every quote below was copied from the source and checked against a saved copy, fetched 2026-10-02. The copies, the certificates, the two filter files, and their SHA-256 hashes are published next to this page (SHA256SUMS).

Exhibit 1 · The claim, 19 August 2025

“Other browsers have deployed similar approaches, but these systems have only been able to store a small fraction of all revoked certificates, necessitating imperfect guesswork as to which ones are most important. CRLite is efficient enough to store all certificate revocations locally, requiring only 300KB per day of continuous updates to stay current.”

blog.mozilla.org/en/firefox/crlite/ · saved copy exhibit_mozilla_blog_crlite.html

Exhibit 2 · What Firefox does when the list can’t answer

// There are a few situations where the user's CRLite data may not cover a
// certificate that chains to our root store, e.g.
//  1) the user has not yet downloaded CRLite filters, or
//  2) the user's CRLite filters are out-of-date, or
//  3) the certificate has been in CT for < 1 MMD interval.
// If we're configured to enforce CRLite and we're configured to tolerate OCSP
// soft failures, then it's reasonable to skip the synchronous OCSP request
// here. In effect, we're choosing to preserve the privacy of the user at the
// risk of potentially allowing them to navigate to a site that is serving a
// revoked certificate.
if (mOCSPFetching == RevocationCheckMayFetch &&
    mCRLiteMode == CRLiteMode::Enforce && mIsBuiltChainRootBuiltInRoot) {
  return Success;
}

security/certverifier/NSSCertDBTrustDomain.cpp, Firefox main branch · saved copy NSSCertDBTrustDomain.cpp · defaults: security.pki.crlite_mode = 2 (enforce), security.pki.crlite_channel = “default” on desktop, “compat” on Android (StaticPrefList-crlite.yaml)

Exhibit 3 · A certificate revoked two minutes after issuance, still good ten days later

CRL:  http://crl.global.sheca.com/govtlscav2a1.crl  (UniTrust, thisUpdate 2026-10-02 09:02 UTC)
serial 11a620cae4d9e34c80122a2affe1bc04  revoked 2026-09-22 16:40:41 UTC
certificate notBefore 2026-09-22 16:38:14 UTC, logs: Xenon2027h1, Argon2027h1, Tiger2027h1

$ rust-query-crlite -d db_default -vvv x509 example-revoked-still-good.der
TRACE - 20260902-0-default.filter: NotCovered
  ... every delta through 20260923-1: NotCovered ...
TRACE - 20260924-0-default.filter.delta: Good
  ... every later delta: Good ...
INFO - example-revoked-still-good.der Good

certificate example-revoked-still-good.der · the CA’s CRL example-crl.der and its entry example-crl-entry.txt · full trace example-query-default.log

Exhibit 4 · Mozilla’s own description of the gap, 16 September 2025

“Certificates that are revoked within the merge delay of the log in which they were discovered may not be marked as revoked until the next full snapshot filter is published. … But in our current configuration this could be up to 45 days after issuance.”

mozilla/crlite issue 367, opened by jschanck · saved crlite-issue-367.json

Exhibit 5 · The same gap after the fix, 13 November 2025

“Unfortunately, clients decide which clubcards to query based on the SCTs that a certificate is presented with. And the embedded SCTs from oak2026h1 and xenon2026h1 do not assert coverage until the 7th. As such, the ‘revoked’ status is masked by an ‘unknown’ status, as in Bug #367. … This problem will more or less resolve itself once CAs start logging precertificates to static CT logs.”

mozilla/crlite issue 376, comment by jschanck · saved crlite-issue-376-comments.json

Exhibit 6 · The filter’s own coverage list

$ inspect 20261002-1-default.filter.delta      (clubcard-crlite example)
Clubcard of size 135568 (108208 + 27360) with 0 exceptions
                  CT Log ID                             Min Time        Max Time
  utuIpG+cr6QJDoLlk1bbbni0pT9YLbCBl5UkLym2jJg=,               0,   1790946101346
  ...
1,078 entries; 44 match a log on the Google or Apple log lists.

saved coverage-20261002-1-default.delta.txt and coverage-20260902-0-default.filter.txt · filter files 20260902-0-default.filter, 20261002-1-default.filter.delta

Our questions to Mozilla

Sent to Mozilla’s CRLite maintainers on 2 October 2026 (mozilla/crlite issue 391). Answers will be printed here as written.

  1. When is the next full filter due? The current snapshot is dated 2 September; the Clubcards paper describes a new one about every 22 days.
  2. Is the figure in our sample, 37 of 108 certificates revoked within 24 hours of issuance showing as good, in line with Mozilla’s own telemetry?
  3. Issue 376 says the gap resolves as CAs move to static logs. Is Mozilla tracking how many newly issued certificates still carry only 24-hour-log timestamps?
  4. Is there a plan to include the uncovered revocations in a delta once their coverage window closes, rather than waiting for the next snapshot?
  5. The coverage list omits 25 of the 68 logs the Google and Apple programs currently qualify, including Cloudflare’s Raio, Geomys’ Trastevere and GoDaddy’s Aquamarine. Is that intended, and what happens to a certificate logged only to those?
  6. Should the blog’s “all certificate revocations” be read as applying to desktop only, given Android’s channel carries three reason codes?

Their reply, scored

Waiting for a reply. When it comes, each question gets marked answered, partly answered or not answered, and the reply goes here in full.

Disclosure timeline

2 OctPublished; sent to Mozilla with the six questions above, as mozilla/crlite issue 391 and by email to the CRLite maintainer.

Waiting on Mozilla since 2 Oct.

What we can’t be sure of

Run it yourself

Python 3 with cryptography, a PostgreSQL client for crt.sh’s public mirror, and Rust for Mozilla’s tools. The CRL pass takes about ten minutes; crt.sh is slow and sometimes refuses connections, so the lookup can take an hour.

python3 sample_crls.py && python3 sample_crls_big.py     # CRLs from CCADB, revocations 2-30 days old
python3 fetch_and_query.py                                 # draws the sample (the fetch inside it is superseded)
python3 fetch_v3.py && python3 fetch_scts.py               # crt.sh lookups, SCT timestamps in UTC
git clone https://github.com/mozilla/crlite && git apply exhibits/rust-query-crlite-raw-subcommand.patch
cargo build --release --manifest-path crlite/rust-query-crlite/Cargo.toml
rust-query-crlite -d db_default --update prod --channel default https example.com
rust-query-crlite -d db_compat  --update prod --channel compat  https example.com
python3 analyze.py                                         # verdicts, tables, results.json

Reproduced from the public repository on 3 October 2026 on a clean machine: the CRL sample and the Firefox query tool build and run (1,320 CRLs parsed, 255,797 revocations in the window, example.com Good against 63 filters). The crt.sh lookups for 1,691 certificates take about an hour. Full table on the track record.

What you can do with this

References

  1. Bobby Holley. Fast, private and secure (pick three): Introducing CRLite in Firefox. Mozilla, 19 August 2025. blog.mozilla.org.
  2. Firefox source, security/certverifier/NSSCertDBTrustDomain.cpp, CheckRevocation. github.com/mozilla-firefox/firefox.
  3. Firefox source, modules/libpref/init/StaticPrefList.yaml: security.pki.crlite_mode, security.pki.crlite_channel; mozilla/crlite rust-query-crlite/README.md on the two channels.
  4. John Schanck. mozilla/crlite issue 367, “Certificates revoked within one CT log MMD of issuance can fail to appear as revoked in delta updates”, 16 September 2025.
  5. mozilla/crlite pull request 369, “storage: hold serials in cache until they are covered”, merged 25 September 2025.
  6. mozilla/crlite issue 376, “revoked-isrgrootx1.letsencrypt.org not showing up as revoked”, 13 November to 5 December 2025.
  7. John M. Schanck and others. Clubcards for the WebPKI: smaller certificate revocation tests in theory and practice. IEEE S&P 2025. research.mozilla.org.
  8. CCADB, Mozilla intermediate certificates with CRL URLs, MozillaIntermediateCertsCSVReport; crt.sh public database, crt.sh:5432/certwatch; Google and Apple CT log lists.

Cite as

@misc{markovian-sm009,
  author = {{Markovian Protocol}},
  title  = {Firefox CRLite against the CAs' own revocation lists, October 2026},
  number = {SM-009},
  doi    = {10.5281/zenodo.23123001},
  year   = {2026},
  month  = oct,
  url    = {https://markovianprotocol.com/measurements/sm-009.html}
}