ERR_CERT_DATE_INVALID: what it means and how to fix it
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
- Exact text
Your connection is not private, withNET::ERR_CERT_DATE_INVALIDunder Advanced; when Chrome decides the device clock is wrong,Your clock is aheadorYour 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]
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].
| Case | Text 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 the server sent | Chrome, text under Advanced | Firefox |
|---|---|---|
| a valid certificate and its intermediate (control) | page loaded | page 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]:
| Device clock | Chrome screen | Below the heading |
|---|---|---|
| 3 days behind | Your connection is not private | "supposedly from tomorrow" under Advanced; a link to proceed |
| 30 days ahead | Your connection is not private | "expired 11 days ago" and the clock question; a link to proceed |
| 1 year behind | Your clock is behind | the code, an Update date and time button, no link to proceed |
| 2 years ahead | Your clock is ahead | the 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
notBeforedate 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 -datesOutput from our test servers
Trusting only the test root, the two tools gave [12]:
| What the server sent | openssl s_client | curl | openssl x509 -dates |
|---|---|---|---|
| a certificate that had expired | verify error:num=10:certificate has expired under depth=0 | (60) SSL certificate problem: certificate has expired | notAfter in the past |
| a certificate not valid yet | verify error:num=9:certificate is not yet valid under depth=0 | (60) SSL certificate problem: certificate is not yet valid | notBefore in the future |
| an expired intermediate | num=10 under depth=1 | certificate has expired | valid dates |
| an intermediate not valid yet | num=9 under depth=1 | certificate is not yet valid | valid 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
Only one visitor sees this. Is my site broken?
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?
Sources
Chromium, net/base/net_error_list.h (CERT_DATE_INVALID -201) and components/error_page_strings.grdp.
Chromium, components/security_interstitials_strings.grdp (certificate warning, clock error screen) and components/security_interstitials/core/bad_clock_ui.cc.
Chromium, components/ssl_errors_strings.grdp and components/ssl_errors/error_info.cc (texts under Advanced).
Chromium, components/ssl_errors/error_classification.cc and components/security_interstitials/content/ssl_error_handler.cc.
Chromium, net/cert/cert_status_flags.cc (MapCertStatusToNetError).
Mozilla Firefox, toolkit/locales/en-US/toolkit/neterror/netError.ftl and nsserrors.ftl.
IETF, RFC 5280 (X.509 certificate profile), sections 4.1.1.3, 4.1.2.5 and 6.1.3.
IETF, RFC 9846 (TLS 1.3), section 6.2.
OpenSSL 3.0, X509_STORE_CTX_get_error (verification error codes); curl, man page (exit code 60).
Microsoft Learn, Browsers and webview controls used by Office Add-ins (Microsoft Edge, Chromium-based).
Bridge SSL, home page (table of browser errors; FAQ).
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.
Chromium, chrome/browser/browser_features.cc, components/network_time/network_time_tracker.cc and net/cert/cert_verify_proc_builtin.cc.