ERR_CERT_AUTHORITY_INVALID: what it means and how to fix it
NET::ERR_CERT_AUTHORITY_INVALID is the code Chrome shows when it cannot link a site's certificate to a root authority it trusts. Chromium's list of network errors describes it as a certificate "signed by an authority we don't trust" [1]. In our test, five different server setups produced this one code. A sixth, a missing intermediate certificate, did not show it in Chrome at all when the certificate gave the browser an address to fetch the intermediate from [13]. So the fix starts with finding out which setup it is. This page is about the Chrome code: Firefox names the same faults SEC_ERROR_UNKNOWN_ISSUER, and the codes for other failures are collected under SSL errors.
Quick facts
- Exact text
Your connection is not private; the codeNET::ERR_CERT_AUTHORITY_INVALIDappears under Advanced [13]- Net error number
- -202 in Chromium's list of network errors [1]
- What failed
- the path from the site's certificate to a trusted root: an intermediate is missing or wrong, or the root is not one the device trusts [13]
- Firefox, same faults
SEC_ERROR_UNKNOWN_ISSUER, orMOZILLA_PKIX_ERROR_SELF_SIGNED_CERTfor a self-signed certificate [5] [13]- Who fixes it
- the site owner, if other HTTPS sites open normally; the owner of the device or network, if every HTTPS site shows it [5]
What the error means
A browser trusts a site's certificate through a certificate chain. The site's certificate is signed by an intermediate authority, and the intermediate by a root. The server sends its own certificate and the intermediates; the root has to be among the root certificates the browser or the operating system already holds. ERR_CERT_AUTHORITY_INVALID means Chrome could not complete that path.
Chromium's comment on the code lists three ways it happens: an attacker has swapped in a certificate signed by an authority of their own, the operator has a certificate from an authority Chromium does not know, or the server presents a self-signed certificate [1]. Under Advanced, Chrome says the site "is using a security certificate that is not trusted by Chrome or your system configuration for web traffic encryption. This may be caused by a misconfiguration, or an attacker intercepting your connection." [2] [13]
What causes it: our test
We served each fault from a test server, with certificates from a test root of our own that both browsers were set to trust, and recorded what each browser showed [13]:
| What the server sent | Chrome | Firefox |
|---|---|---|
| its certificate and the intermediate (control) | page loaded | page loaded |
| its certificate only, without the intermediate | NET::ERR_CERT_AUTHORITY_INVALID | SEC_ERROR_UNKNOWN_ISSUER |
| its certificate only, which carried the intermediate's address | page loaded | SEC_ERROR_UNKNOWN_ISSUER |
| its certificate with an intermediate from another chain | NET::ERR_CERT_AUTHORITY_INVALID | SEC_ERROR_UNKNOWN_ISSUER |
| a full chain to a root the browsers did not trust | NET::ERR_CERT_AUTHORITY_INVALID | SEC_ERROR_UNKNOWN_ISSUER |
| the same chain with that root added | NET::ERR_CERT_AUTHORITY_INVALID | SEC_ERROR_UNKNOWN_ISSUER |
| a self-signed certificate | NET::ERR_CERT_AUTHORITY_INVALID | MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT |
Adding the untrusted root to what the server sent changed nothing in either browser [13]. A root counts only if the device already trusts it.
Antivirus or proxy software that inspects HTTPS, on a device where its root is not installed, is in the same position as the untrusted-root rows. When Chrome can name such software, it shows a separate screen. On a managed device, its explanation says a root certificate for that software "is required but isn’t installed"; on other devices, that the software "isn’t configured correctly". The applications it names are "antivirus, firewall, and web-filtering or proxy software" [2].
Why the site loads in one browser and fails in another
The third row is the split. The certificate carried the address of its intermediate in the Authority Information Access field (RFC 5280, section 4.2.2.1) [7]. Chrome downloaded the intermediate from that address and loaded the page; our test server logged one request from Chrome and none from Firefox [13]. Chromium's verifier has a component that retrieves issuers from these addresses [4]. Desktop Firefox instead preloads the intermediates that public authorities disclose, and our test authority is not among them, so a publicly trusted certificate may load in Firefox where ours failed [6].
What we did not see was a browser remembering an intermediate from an earlier connection. In a fresh session, each browser first opened the control server, which sent the intermediate, and then the server that left it out of the certificate chain: both still showed the error. After Chrome had fetched the intermediate for one server, a second server without the address failed too [13].
How to fix it
For site owners
Match the cause to a row of the table, then change what the server sends:
No intermediate. Serve your certificate followed by the intermediates. In nginx they go in the one file named by
ssl_certificate, your certificate first; in Apache 2.4.8 and later,SSLCertificateFilecan hold the intermediates as well, in order from your certificate towards the root [9].The wrong intermediate. The intermediate has to be the one that signed your certificate: in our test, an intermediate from another chain gave the same error as none at all [13]. Install the chain that came with the current certificate, not a bundle kept from an earlier one.
A private or internal authority. Visitors' devices do not trust its root, and sending the root does not change that [13]. A public site needs a certificate from an authority browsers trust. For internal sites, the root has to be installed on every device that should trust it.
A self-signed certificate. The same applies: browsers have no root to check it against.
TLS ends at a load balancer, proxy or CDN. Check what that layer sends, not the server behind it.
After the change, check with curl or openssl s_client, as in the terminal check below, rather than from your browser: neither fetched a missing intermediate in our test [13].
For visitors
One site fails, others open. If Chrome shows Your connection is not private with this code on one site only, the fault is at the site, and only its owner can fix the certificate. In Firefox, the page for this fault says "there is nothing you can do to resolve it" [5]. Tell the owner the code.
Every HTTPS site fails. The cause is then on your device or network, not at the sites: software that inspects HTTPS without its root installed, as described above [2]. Firefox's advice is to turn off the antivirus feature that scans encrypted connections, "often called “web scanning” or “https scanning”", and, on a corporate network, to contact the IT department [5]. On a managed work device, ask the IT team, which installs the root certificate of its inspection software.
Try another network. If the sites open on mobile data and fail on the first network, the cause is on that network.
How to check the chain from a terminal
Unlike Chrome, curl and OpenSSL did not fetch the missing intermediate in our test, and curl lists that feature as not done [10] [13], so their output shows what the server sends:
$ openssl s_client -connect example.com:443 -servername example.com </dev/null
$ curl -sS https://example.com/ -o /dev/nullOutput against our test servers, trusting only the test root [13]:
| What the server sent | openssl s_client | curl |
|---|---|---|
| its certificate only, with or without the intermediate's address | Verify return code: 21 (unable to verify the first certificate) | (60) SSL certificate problem: unable to get local issuer certificate |
| an intermediate from another chain | 21 (unable to verify the first certificate) | same as above |
| a full chain to an untrusted root | 20 (unable to get local issuer certificate) | same as above |
| the same chain with the root added | 19 (self-signed certificate in certificate chain) | self-signed certificate in certificate chain |
| a self-signed certificate | 18 (self-signed certificate) | self-signed certificate |
curl exited with code 60 in every row: a peer certificate that cannot be authenticated with known CA certificates [10]. The first three curl lines are the error covered on unable to get local issuer certificate. Under Certificate chain, s_client lists what was sent; a list that ends at your certificate, whose i: line names an intermediate, means it was not sent [13].
What the server log shows
The rejecting client also tells the server, with an alert. In our test, curl and openssl s_client -verify_return_error sent unknown_ca (48), and Chrome sent certificate_unknown (46) [13]. RFC 9846 defines unknown_ca as a chain that was received but whose CA certificate could not be located or could not be matched with a known trust anchor, and certificate_unknown as some other issue with the certificate (section 6.2) [8]. An OpenSSL server logs them as tlsv1 alert unknown ca and sslv3 alert certificate unknown [13]; reading alerts from both ends is covered on SSL handshake failed: causes and fixes.
When Chrome shows a different code
One fault in the chain gave a different code in our test [13]:
| What the server sent | Chrome | Firefox |
|---|---|---|
| a full chain whose intermediate had expired | NET::ERR_CERT_DATE_INVALID | SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE |
An expired intermediate counts as a date problem, the code described on NET::ERR_CERT_DATE_INVALID [13]. When one certificate has several faults, Chrome reports the most serious: in Chromium's order, a revoked certificate comes before an untrusted authority, which comes before a wrong name and, further down, the dates [3]. So once the chain is fixed, a name or date fault on the same certificate can appear under its own code.
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].
How to prevent it
Install the certificate and its chain in the same step, from the same delivery, and check the chain from outside after every certificate change. A bundle kept apart from the certificate can stop matching it, and our test showed that a mismatched intermediate fails like a missing one [13]. Automating issuance and installation removes the step where the chain is put together by hand.
Fix this with Bridge SSL
On Bridge CDN, TLS is terminated at the edge: there is no certificate file on your machine and no chain to assemble [12]. See what the platform includes at Bridge CDN.
FAQ
What does ERR_CERT_AUTHORITY_INVALID mean?
Why does the site work for some people and not others?
Browsers fill a missing intermediate in different ways. In our test, Chrome downloaded it from the address in the certificate and loaded the page, while Firefox showed SEC_ERROR_UNKNOWN_ISSUER. Desktop Firefox preloads the intermediates of public authorities, so the split depends on the certificate too. [6] [13]
Can I fix it as a visitor?
Only if the cause is on your side. If every HTTPS site shows the warning, antivirus HTTPS scanning or a proxy on your network is the place to look. If only one site does, the certificate is the site's to fix. [5]
How do I check my chain is complete?
Run openssl s_client against the hostname and look at the certificate list and the Verify return code line. If the list holds only your own certificate, whose issuer line names an intermediate, the server does not send that intermediate. A check in your own browser can pass, because Chrome may fetch the intermediate itself. [13]
Sources
Chromium, net/base/net_error_list.h (CERT_AUTHORITY_INVALID -202, CERT_DATE_INVALID, SSL_PROTOCOL_ERROR) and components/error_page_strings.grdp (error page headings).
Chromium, components/ssl_errors_strings.grdp (IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS_V2) and components/security_interstitials_strings.grdp (IDS_MITM_SOFTWARE_EXPLANATION).
Chromium, net/cert/cert_status_flags.cc (MapCertStatusToNetError).
Chromium, net/cert/internal/cert_issuer_source_aia.h.
Mozilla Firefox, toolkit/locales/en-US/toolkit/neterror/netError.ftl and nsserrors.ftl.
Mozilla Security Blog, Preloading Intermediate CA Certificates into Firefox.
IETF, RFC 5280, Internet X.509 Public Key Infrastructure Certificate and CRL Profile, section 4.2.2.1.
IETF, RFC 9846, The Transport Layer Security (TLS) Protocol Version 1.3, section 6.2.
nginx, Configuring HTTPS servers (SSL certificate chains); Apache HTTP Server 2.4, mod_ssl, SSLCertificateFile directive.
OpenSSL 3.0, X509_STORE_CTX_get_error (verification error codes); curl, man page (exit code 60) and TODO (Authority Information Access).
Microsoft Learn, Browsers and webview controls used by Office Add-ins (Microsoft Edge, Chromium-based).
Bridge SSL, home page (What happens on my server?).
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, curl and OpenSSL 3.0 clients.