Certificate Validity Dates

Back in 2017 the maximum validity lifetime for an HTTPS certificate was set to 825 days, a decision that was widely supported by both browsers and certificate authorities. However, since then there have been multiple unsuccessful attempts at reducing the maximum lifetime to one year. Scott Helme has written about this previously, and his blog post noted that browser vendors unanimously supported this while some certificate authorities objected to it.

Information is still trickling in, but it seems that Safari is planning to enforce a max validity lifetime of 398 days effective September 1st, 2020.

Let’s take a look at the state of certificate validity ranges today, so we can track how this evolves over the next few months.

Certificate Validity Dates in the Wild

The HTTP Archive requests table contains certificate details for every HTTPS request that was served to the 5.3 million websites tracked. The details are in the $._securityDetails and the data contains information on 4,397,690 unique hosts. Out of all of these, 136,007 hostnames served a validity date greater than 825 days! That’s 3.09% of all requests!

Certificate validity dates are widely distributed, but there seems to be a few popular ranges. THe most common validity date is 90 days, likely to the popularity of LetsEncrypt Overall 55% of certificates have a validity date of less than 364 days, which I’ve highlighted in green below. An additional 20% of certificates have a validity between 365 and 398 days, which will meet Safari’s requirements. The remaining 25% have a validity range of more than 398 days.

Looking at this by certificate authority is also quite interesting. The graph below shows the top 15 certificate authorities. LetsEncrypt accounts for 38.4% of all certificates -

When we look at certificate validity date ranges for these certificate authorities, we can see that there’s a mix. Certificates issued by LetsEncrypt, Cloudflare, cPanel and Amazon meet the 398 day requirement already. However, Sectigo, GoDaddy, DigiCert, Comodo and RapidSSL have a very large percentage of certificates that exceed 398 days.

DigiCert released a public statement yesterday, which confirms that existing certificates with a validity range >398 days will continue to be trusted by Safari, but that certificates issued after August 30th won’t be able to exceed 398 days.

For your website to be trusted by Safari, you will no longer be able to issue publicly trusted TLS certificates with validities longer than 398 days after Aug. 30, 2020. Any certificates issued before Sept. 1, 2020 will still be valid, regardless of the validity period (up to 825 days). Certificates that are not publicly trusted can still be recognized, up to a maximum validity of 825 days.

I’m interested in seeing how this will evolve in the coming months, especially once there are more formal announcements about this.

Many thanks to Scott Helme for reviewing this.


The following SQL query was used to extract all of the certificate details needed for this analysis. Please note that it processes 2.84TB, which exceeds the free tier of BigQuery. I’ve copied the results to httparchive.scratchspace.certificateValidityDates_20200101_mobile where we can do further analysis with a smaller dataset:

  SELECT DISTINCT
    NET.HOST(url),
    JSON_EXTRACT_SCALAR(payload, '$._securityDetails.validFrom')   AS validFrom,
    JSON_EXTRACT_SCALAR(payload, '$._securityDetails.validTo')     AS validTo,
    JSON_EXTRACT_SCALAR(payload, '$._securityDetails.issuer')      AS issuer,
    JSON_EXTRACT_SCALAR(payload, "$._securityDetails.subjectName") AS subjectName,
    JSON_EXTRACT       (payload, '$._securityDetails.sanList')     AS sanList
  FROM
    `httparchive.requests.2020_01_01_mobile` 
  WHERE url LIKE "https://%"
    AND  JSON_EXTRACT_SCALAR(payload, '$._securityDetails.validFrom') IS NOT NULL
    AND  JSON_EXTRACT_SCALAR(payload, '$._securityDetails.validTo') IS NOT NULL

This query was used to summarize the validity ranges for all certificates.


SELECT 
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) < 90, 1,0)) AS LessThan90Days,
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) = 90, 1,0)) AS _90Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 91 AND 364, 1,0)) AS _91_364Days,
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 364 AND 398, 1,0)) AS _364_398Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 399 AND 730, 1,0)) AS _366_730Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) = 731, 1,0)) AS _731Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) > 731, 1,0)) AS GreateThan_731Days,
       COUNT(*) AS total
FROM 
  `httparchive.scratchspace.certificateValidityDates_20200101_mobile`

This query was used to summarize the validity ranges based on the certificate authorities.


SELECT 
       issuer,
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) < 90, 1,0)) AS LessThan90Days,
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) = 90, 1,0)) AS _90Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 91 AND 364, 1,0)) AS _91_364Days,
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 364 AND 398, 1,0)) AS _364_398Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) BETWEEN 399 AND 730, 1,0)) AS _366_730Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) = 731, 1,0)) AS _731Days,  
       SUM(IF(ROUND((CAST(validTo as INT64) - CAST(validFrom as INT64)) / (60*60*24)) > 731, 1,0)) AS GreateThan_731Days,
       COUNT(*) AS total
FROM 
  `httparchive.scratchspace.certificateValidityDates_20200101_mobile`
GROUP BY 
  issuer
ORDER BY 
  total DESC
1 Like