ERR_CERT_DATE_INVALID: what it means and how to fix it

12 min readUpdated

NET::ERR_CERT_DATE_INVALID is the code Chrome shows when a certificate is out of date by the clock of the device that checks it. Chromium's list of network errors describes a certificate that, "by our clock, appears to either not yet be valid or to have expired", and gives three meanings: an attacker presenting an old certificate whose private key they obtained, a misconfigured server that is not presenting a valid certificate, or a wrong clock on the device [1]. In our test, an expired certificate, one that was not valid yet, an intermediate in either state and, in a browser without network time, a wrong device clock all gave this one code [12]. The screen Chrome shows and the text under Advanced are the first clues to which is wrong, the certificate or the clock. This page is about the Chrome code: Firefox names the same faults with codes of its own, and codes for other failures are under SSL errors.

Quick facts

Browsers
Chrome and other browsers built on Chromium, such as Microsoft Edge [1][10]
Exact text
Your connection is not private, with NET::ERR_CERT_DATE_INVALID under Advanced; when Chrome decides the device clock is wrong, Your clock is ahead or Your clock is behind, with the code on the same screen [2][12]
Net error number
-201 in Chromium's list of network errors [1]
What failed
the time Chrome checks against falls outside the validity period of the site's certificate or of its intermediate [7][13]
Firefox, same faults
SEC_ERROR_EXPIRED_CERTIFICATE and MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE; for an intermediate, SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE and MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE [6][12]
Who fixes it
the site owner, if a certificate is out of date; the owner of the device, if its clock is wrong [1][2]

What the error means

A certificate is valid from its notBefore date through its notAfter date, inclusive (RFC 5280, section 4.1.2.5) [7]. During path validation, each certificate in the chain, the site's own and each intermediate certificate above it, must have a validity period that includes the current time (section 6.1.3) [7]. On Android and desktop platforms other than ChromeOS, Chrome checks the dates against network time when it has it, unless a policy turns that off, and retries with the device clock only if the check fails [13]. Without network time, the device clock decides, so the same certificate can pass on one device and fail on another [1][12][13].

What the text under Advanced says

Chrome uses one code for every way this check fails. The explanation under Advanced tells the cases apart: Chrome picks it by comparing the site's own certificate with the clock [3].

What the text under Advanced says
CaseText under Advanced in Chrome
the site's certificate has expired"its security certificate expired n days ago. … Your computer's clock is currently set to … Does that look right? If not, you should correct your system's clock and then refresh this page."
the site's certificate is not valid yet"its security certificate is supposedly from n days in the future."
any other date fault, such as an out-of-date intermediate"its security certificate is not valid at this time."

Each text begins "This server could not prove that it is" followed by the site's name, and adds "This may be caused by a misconfiguration or an attacker intercepting your connection." [3] Chromium's comment on the third case names two reasons for it: an intermediate or root certificate has expired, or the certificate has become valid since the error occurred [3]. Only the expired case asks about the clock.

What causes it: our test

We served each fault from a test server, with certificates from our own test root that both browsers trusted, and recorded what each showed [12]:

What causes it: our test
What the server sentChrome, text under AdvancedFirefox
a valid certificate and its intermediate (control)page loadedpage loaded
a certificate that had expired two days before"expired 3 days ago"SEC_ERROR_EXPIRED_CERTIFICATE
a certificate valid from three days later"supposedly from 2 days in the future"MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE
a valid certificate with an expired intermediate"not valid at this time"SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE
a valid certificate with an intermediate valid from three days later"not valid at this time"MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE

Every failing row showed Your connection is not private with NET::ERR_CERT_DATE_INVALID and a link to proceed [12]. Chromium rounds the days since expiry up, so a certificate that had expired two days and a few minutes earlier read "3 days ago"; a start a few minutes short of three days ahead read "2 days" [3][12]. In the two intermediate rows, the site's own certificate was valid, and Chrome's text did not say which certificate was at fault [12].

When the device clock is wrong

We then moved the clock that Chrome sees, leaving the server's clock alone, and opened the control server, whose certificate was valid from a day before the test to 20 days after it [12]:

When the device clock is wrong
Device clockChrome screenBelow the heading
3 days behindYour connection is not private"supposedly from tomorrow" under Advanced; a link to proceed
30 days aheadYour connection is not private"expired 11 days ago" and the clock question; a link to proceed
1 year behindYour clock is behindthe code, an Update date and time button, no link to proceed
2 years aheadYour clock is aheadthe same

Outside Android and iOS, the clock screen says "A private connection to" the site "can't be established because your computer's date and time" are incorrect [2]. Chrome shows it only when it judges the clock wrong: by network time, beyond a margin of 5 minutes plus its uncertainty, or, without network time, when the clock is more than 2 days before the browser's build date or more than 365 days after it [4]. With network time, a valid certificate passes even when the device clock is wrong [13]. Our test browser had no network time, so clocks 3 days behind and 30 days ahead got the ordinary screen [12]. The clock screen offers no way to proceed [2].

How to fix it

For visitors

  • Chrome says your clock is ahead or behind. Set the date and time. Where Chrome can open the system's date and time settings, the screen has an Update date and time button for that [2]. Then reload the page.

  • The ordinary warning. Check the date, time and time zone on your device first: for an expired certificate, the text under Advanced shows the date your computer is set to and asks "Does that look right?" [3]. Firefox's advice for the same fault: "Make sure your computer is set to the correct date, time, and time zone in your system settings" [6].

  • The clock is right. Then the certificate is the site's to fix. Firefox says: "If your clock is already set to the right time, the website is likely misconfigured, and there is nothing you can do to resolve the issue." [6] Tell the owner the code and the line under Advanced.

For site owners

Find the case from the text under Advanced or the terminal check, then:

  • The certificate has expired. Its dates are inside the signed part of the certificate and cannot be changed without breaking the signature [7]. Certificate renewal issues a replacement with new dates. Restoring service after expiry is covered on the expired certificate page.

  • The certificate is not valid yet. Its notBefore date is still in the future, and the error stays until that time [7]. Serve a certificate that is valid now.

  • An intermediate is out of date. Install the intermediate that came with the current certificate; the terminal check below shows its dates.

How to check the dates from a terminal

Run the check on a machine whose clock you trust: OpenSSL compares the dates with the current time of the machine it runs on [9][12]. The first command prints the verification result and, under Certificate chain, a v:NotBefore: …; NotAfter: … line for each certificate the server sends, its own and the intermediate certificate: unlike the text in Chrome, it shows which one is out of date. The second prints the site's own dates only [12]:

$ openssl s_client -connect example.com:443 -servername example.com </dev/null
$ openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates

Output from our test servers

Trusting only the test root, the two tools gave [12]:

Output from our test servers
What the server sentopenssl s_clientcurlopenssl x509 -dates
a certificate that had expiredverify error:num=10:certificate has expired under depth=0(60) SSL certificate problem: certificate has expirednotAfter in the past
a certificate not valid yetverify error:num=9:certificate is not yet valid under depth=0(60) SSL certificate problem: certificate is not yet validnotBefore in the future
an expired intermediatenum=10 under depth=1certificate has expiredvalid dates
an intermediate not valid yetnum=9 under depth=1certificate is not yet validvalid dates

depth=0 is the site's own certificate and depth=1 the intermediate above it [12]. In OpenSSL, code 9 means the notBefore date is after the current time, and code 10 that the notAfter date is before it [9][12]. curl exited with code 60, a peer certificate that cannot be authenticated with known CA certificates, in every failing row [9][12]. With an out-of-date intermediate, openssl x509 -dates shows two good dates, because it reads only the first certificate [12].

What the server log shows

The rejecting client also tells the server, with an alert. In our test, openssl s_client -verify_return_error and curl sent certificate_expired (45), and Chrome sent certificate_unknown (46) [12]. RFC 9846 defines certificate_expired as "A certificate has expired or is not currently valid", and certificate_unknown as some other, unspecified issue in processing the certificate (section 6.2) [8]. An OpenSSL server logs them as sslv3 alert certificate expired and sslv3 alert certificate unknown [12], so the log line from Chrome does not say that the dates were the fault. Reading alerts from both ends is covered on SSL handshake failed: what the alert means.

When Chrome shows a different code

When one certificate has several faults, Chrome reports the most serious, and the dates come late in Chromium's order: a revoked certificate, an untrusted authority and a wrong name are among the faults reported before them [5]. So an expired certificate from an authority the device does not trust shows ERR_CERT_AUTHORITY_INVALID, and the date fault appears under this code once the other faults are fixed [5].

When the handshake fails for a reason other than the certificate, Chrome shows a different screen, "This site can’t provide a secure connection", with a code such as ERR_SSL_PROTOCOL_ERROR [1].

Fix this with Bridge SSL

Bridge SSL obtains certificates on demand and renews them ahead of expiry, without a published guaranteed time for either. Its home page lists this error as removed only partly: a wrong device clock stays [11]. Keep an independent check on what your hostnames present [11]. See what the platform includes at Bridge CDN.

FAQ

What does NET::ERR_CERT_DATE_INVALID mean?

Chrome found a certificate whose validity dates do not include the time it checks against. The site's certificate or its intermediate has expired or is not valid yet, or the device clock is wrong. [1][12]

Only one visitor sees this. Is my site broken?

Probably not, if other browsers accept the same certificate. A browser without network time checks the dates against the device clock, so a device with a wrong date can fail on a certificate that works everywhere else. Ask what date and time that device shows. [1][12][13]

Why does Chrome say my clock is ahead or behind?

Chrome decided that the clock is wrong rather than the certificate: by network time or, without it, by the date the browser was built. That screen has no link to proceed. [2][4][12]

The certificate dates look right. Why does the error stay?

Check the intermediate. In our test, an expired intermediate and one that was not valid yet both gave this code while the site's own certificate was valid, and Chrome said only "not valid at this time". The certificate list from openssl s_client shows the dates of each certificate the server sends. [3][12]

Is it safe to proceed?

Chrome offers a link to proceed, marked unsafe, on the ordinary screen, and none on the clock screen or on a site that uses HSTS. Its text names both a misconfiguration and an attacker intercepting the connection as possible causes, so do not continue on a site where you sign in or pay. [2][3][12]

Sources

  1. Chromium, net/base/net_error_list.h (CERT_DATE_INVALID -201) and components/error_page_strings.grdp.

  2. Chromium, components/security_interstitials_strings.grdp (certificate warning, clock error screen) and components/security_interstitials/core/bad_clock_ui.cc.

  3. Chromium, components/ssl_errors_strings.grdp and components/ssl_errors/error_info.cc (texts under Advanced).

  4. Chromium, components/ssl_errors/error_classification.cc and components/security_interstitials/content/ssl_error_handler.cc.

  5. Chromium, net/cert/cert_status_flags.cc (MapCertStatusToNetError).

  6. Mozilla Firefox, toolkit/locales/en-US/toolkit/neterror/netError.ftl and nsserrors.ftl.

  7. IETF, RFC 5280 (X.509 certificate profile), sections 4.1.1.3, 4.1.2.5 and 6.1.3.

  8. IETF, RFC 9846 (TLS 1.3), section 6.2.

  9. OpenSSL 3.0, X509_STORE_CTX_get_error (verification error codes); curl, man page (exit code 60).

  10. Microsoft Learn, Browsers and webview controls used by Office Add-ins (Microsoft Edge, Chromium-based).

  11. Bridge SSL, home page (table of browser errors; FAQ).

  12. Our test setup: Python HTTPS servers and an OpenSSL 3.0 server with certificates from a test authority of our own, Chrome and Firefox in headless mode, a faked clock, curl and OpenSSL 3.0 clients.

  13. Chromium, chrome/browser/browser_features.cc, components/network_time/network_time_tracker.cc and net/cert/cert_verify_proc_builtin.cc.