This blog post applies when the following two cases are true:
Your browser does not complain about your https site. Everything seems fine.
Some other tool does complain about not finding your certificate or not finding intermediate certificates. What is the problem?
So: your browser doesn’t complain. Let’s see a screenshot:
Some examples of complaining tools. First
$ curl https://api.letsgxxxxxxx curl: (60) SSL certificate problem: Invalid certificate chain More details here: http://curl.haxx.se/docs/sslcerts.html curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.
curl has the right error message: Invalid certificate chain.
Let us look at
$ wget https://api.letsgxxxxxx --2015-11-23 10:54:28-- https://api.letsgxxxxx Resolving api.letsgxxxxxx... 18.104.22.168 Connecting to api.letsgxxxxxx|22.214.171.124|:443... connected. ERROR: cannot verify api.letsgxxxxxx's certificate, issued by 'CN=COMODO RSA Domain Validation Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB': Self-signed certificate encountered. To connect to api.letsgxxxxxx insecurely, use `--no-check-certificate'.
wget is right that it cannot verify …. certificate. But its
conclusion Self-signed certificate encountered is less helpful. The
certificate is not self-signed, it is just that
wget has to treat it that
way because the certificate chain is incorrect.
If you talk to such an https URL with java, you can see an error like this:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This looks quite cryptic, but the cause is the same. SunCertPathBuilderException: CertPath sure sounds like a path to a certificate that it cannot find.
A final example is with the python
>>> import requests >>> requests.get('https://api.letsgxxxxxx') Traceback (most recent call last): File "<console>", line 1, in <module> File "/requests/api.py", line 69, in get return request('get', url, params=params, **kwargs) File ".../requests/api.py", line 50, in request response = session.request(method=method, url=url, **kwargs) File ".../requests/sessions.py", line 465, in request resp = self.send(prep, **send_kwargs) File ".../requests/sessions.py", line 573, in send r = adapter.send(request, **kwargs) File ".../requests/adapters.py", line 431, in send raise SSLError(e, request=request) SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)
So… you yourself discover the problem. Or a customer calls that he’s getting an error like this. Even though everything seems right if you test the https site in the browser.
Solution: go to https://www.digicert.com/help/
If that site says everything is completely right, then you’re done. If it still complains about something, you’ve got work to do.
Most of the checkmarks are probably green:
In cases like this, the problem is in the certificate chain at the bottom of the page. Here’s an example of one of our own sites from a few months ago:
Note the “broken chain” icon halfway. Just follow the chain from top to
bottom. Everything has to be perfect. We start with the
which is issued by
GeoTrust SSL CA - G2.
GeoTrust SSL CA - G2 in turn is issued by
The problem: the next certificate in the chain is not about
Global CA, but about
GeoTrust SSL CA, which is different. Here the chain
breaks. It does not matter that the fourth certificate is about the
Global CA we were looking for. The chain is broken. The order in which
the certificates are placed must be perfect.
After fixing the order of the certificates in our certificate file, the problem was fixed:
There are lots of certificates in the wild. All the browsers (and java, and your OS and…) often only store a handful (well, 20+) “root certificates”. All the other certificates have to trace their origin back to one of those root certificates.
That is where the intermediate certificates come in: they’re a cryptographically signed way to trace the validity of your certificate back to one of the known-good root certificates.
If you’re handling certificates yourself, you ought to know which files to edit. The main problem will be getting the right intermediary certificates from the issuing party. Often you only get “your” certificate, not the intermediary ones. Ask about it or google for it.
Often you won’t maintain those certificates yourself. So you have to get your hosting service to fix it.
If you let someone else take care of the certificate, point them at https://www.digicert.com/help/ and tell them to make sure that page is completely happy.
In my experience (=three times in the last two years!) they’ll mail back with “everything works now”. But it still won’t work. Then you’ll have to mail them again and tell them to really check https://www.digicert.com/help/ and probably provide screenshots.
My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):