When encountering the "unable to get local issuer certificate" error with curl, it typically indicates that the client cannot verify the complete certificate chain. In this specific case with Thawte certificates, the issue stems from intermediate certificates not being properly recognized by the local system.
First, let's examine the certificate chain using OpenSSL:
echo | openssl s_client -showcerts -connect example.com:443 -servername example.com
For a more detailed curl analysis:
curl -v --trace-ascii debug.log https://example.com
The error typically occurs due to:
- Missing intermediate certificates in server configuration
- Outdated CA certificates on the client machine
- Incorrect certificate path configuration in curl
- Certificate chain validation failures
Solution 1: Force curl to use specific CA bundle
curl --cacert /path/to/cacert.pem https://example.com
Solution 2: Temporarily bypass verification (for testing only)
curl -k https://example.com
Solution 3: Update CA certificates on Debian
sudo apt-get install ca-certificates
sudo update-ca-certificates --fresh
Solution 4: Verify certificate chain manually
openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt /tmp/servercert.pem
For deeper analysis, use OpenSSL to verify certificate chains:
openssl s_client -showcerts -verify 5 -connect example.com:443 < /dev/null
To inspect the certificate chain order:
openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout
Configure curl to always use the correct CA path by adding to your ~/.curlrc
:
cacert = /etc/ssl/certs/ca-certificates.crt
capath = /etc/ssl/certs/
For system-wide configuration in PHP:
// In php.ini
openssl.cafile=/etc/ssl/certs/ca-certificates.crt
openssl.capath=/etc/ssl/certs/
For Thawte certificates specifically, ensure you have the intermediate certificate:
wget https://www.thawte.com/roots/thawte_Primary_Root_CA.pem
sudo cp thawte_Primary_Root_CA.pem /usr/local/share/ca-certificates/
sudo update-ca-certificates
When encountering the "unable to get local issuer certificate" error with curl on Debian/LAMP systems after PHP 7 updates, the core issue typically stems from incomplete certificate chain verification. The error occurs when curl cannot find the intermediate certificate needed to complete the trust chain back to a trusted root.
openssl s_client -showcerts -connect example.com:443 -servername example.com
This command reveals the complete certificate chain being presented by the server. In our case, we can see:
Certificate chain
0 s:/C=DE/ST=XYZ/CN=*.example.com
i:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
1 s:/C=US/O=thawte, Inc./CN=thawte SSL CA - G2
i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
First, verify your CA certificates are properly configured:
curl --version | grep -i ssl
This should show the CA path being used. Common locations include:
- /etc/ssl/certs
- /etc/pki/tls/certs
- /usr/local/ssl/certs
For PHP applications using cURL, you may need to explicitly set the CA path:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com");
curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt');
curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($ch);
To identify exactly which certificate is missing:
openssl verify -show_chain -CApath /etc/ssl/certs /path/to/server_cert.pem
This will show you the complete verification chain and pinpoint where it breaks.
Sometimes the issue lies with incomplete certificate chains on the server side. Verify the server is sending intermediate certificates:
openssl s_client -connect example.com:443 -servername example.com | openssl x509 -noout -text
The most reliable solution is often to update your certificate bundle:
wget https://curl.se/ca/cacert.pem -O /etc/ssl/certs/ca-certificates.crt
update-ca-certificates --fresh
c_rehash /etc/ssl/certs
For development environments only, you can bypass verification:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
But this creates security vulnerabilities and should never be used in production.
After implementing changes, verify with:
curl -Iv https://example.com
You should see verification succeed with output showing the complete certificate chain.