[php] PHP - SSL certificate error: unable to get local issuer certificate

I'm running PHP Version 5.6.3 as part of XAMPP on Windows 7.

When I try to use the Mandrill API, I'm getting the following error:

Uncaught exception 'Mandrill_HttpError' with message 'API call to messages/send-template failed: SSL certificate problem: unable to get local issuer certificate'

I already tried everything I read on StackOverflow, including adding the following to the php.ini file:

curl.cainfo = "C:\xampp\php\cacert.pem"

And ofcourse downloaded to that location the cacert.pem file from http://curl.haxx.se/docs/caextract.html

but after all that, restarted XAMPP and Apache server but still getting the same error.

I really don't know what else to try.

Can anyone advise on what else can I try?

This question is related to php ssl curl xampp mandrill

The answer is


If none of the solutions above are working for you try updating your XAMPP installation to a newer version.

I was running XAMPP with php 5.5.11, the same exact code didn't work, I upgraded to XAMPP with php 5.6.28 and the solutions above worked.

Additionally only updating PHP didn't work either seems like a combination of apache and php settings on that version of XAMPP.

Hope it helps someone.


I got the error like :

failed loading cafile stream: `C:\xamppPhp\apache\bin\curl-ca-bundle.crt`

I am using windows machine. So I followed the below steps.

1. I have downloaded .pem file from " https://curl.haxx.se/docs/caextract.html "

2. Then I kept the downloaded file inside  "C:/xamppPhp/apache/bin/" folder and renamed the same downloaded file to "curl-ca-bundle.crt".

3. I restarted XAMPP and cleared the cache.
4. It's done.

Hope it may help someone


I had the same issue during building my app in AppVeyor.

  • Download https://curl.haxx.se/ca/cacert.pem to c:\php
  • Enable openssl echo extension=php_openssl.dll >> c:\php\php.ini
  • Locate certificateecho curl.cainfo=c:\php\cacert.pem >> c:\php\php.ini

elaborating on the above answers for server deployment.

$hostname = gethostname();
if($hostname=="mydevpc")
{
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
}

should do the trick for development environment without compromising the server when deployed.


I was facing a problem like this in my local system but not in the live server. I also mentioned another solution on this page its before, but that was not working in localhost.so find a new solution of this, that is working in the localhost-WAMP Server.

cURL Error #:SSL certificate problem: unable to get local issuer certificate

sometimes system could not find your cacert.pem in your drive. so you can define this in your code where you are going to use CURL

Note that i am fulfilling all conditions for this like OPEN-SSL library active and other things.

check this code of CURL.

 $curl = curl_init();
 curl_setopt_array($curl, array(
            CURLOPT_URL =>$url,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "GET",
            CURLOPT_RETURNTRANSFER=> true,
        ));
curl_setopt($curl, CURLOPT_CAINFO, "f:/wamp/bin/cacert.pem"); // <------ 
curl_setopt($curl, CURLOPT_CAPATH, "f:/wamp/bin/cacert.pem"); // <------
$response = json_decode(curl_exec($curl),true);
$err = curl_error($curl);
curl_close($curl);

but this solution may not work in live server. because of absolute path of cacert.pem


Disclaimer: This code makes your server insecure.

I had the same problem in Mandrill.php file after line number 65 where it says $this->ch = curl_init();

Add following two lines:

curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);

This solved my problem and also sent email using localhost but I suggest to NOT use it on live version live. On your live server the code should work without this code.


I found new Solution without any required certification to call curl only add two line code.

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

If you don't have access to php.ini, adding this code (after your $ch = curl_init(); line) works for me:

$certificate_location = "C:\Program Files (x86)\EasyPHP-Devserver-16.1\ca-bundle.crt"; // modify this line accordingly (may need to be absolute)
curl_setopt($ch, CURLOPT_CAINFO, $certificate_location);
curl_setopt($ch, CURLOPT_CAPATH, $certificate_location);

Then, you will just need to download ca-bundle.crt and save it to location you specified in $certificate_location.


When you view the http://curl.haxx.se/docs/caextract.html page, you will notice in big letters a section called:

RSA-1024 removed

Read it, then download the version of the certificates that includes the 'RSA-1024' certificates. https://github.com/bagder/ca-bundle/blob/e9175fec5d0c4d42de24ed6d84a06d504d5e5a09/ca-bundle.crt

Those will work with Mandrill.

Disabling SSL is a bad idea.


for guzzle you can try this :

$client = new Client(env('API_HOST'));
$client->setSslVerification(false);

tested on guzzle/guzzle 3.*


I have a proper solution of this problem, lets try and understand the root cause of this issue. This issue comes when remote servers ssl cannot be verified using root certificates in your system's certificate store or remote ssl is not installed along with chain certificates. If you have a linux system with root ssh access, then in this case you can try updating your certificate store with below command:

update-ca-certificates

If still, it doesn't work then you need to add root and interim certificate of remote server in your cert store. You can download root and intermediate certs and add them in /usr/local/share/ca-certificates directory and then run command update-ca-certificates. This should do the trick. Similarly for windows you can search how to add root and intermediate cert.

The other way you can solve this problem is by asking remote server team to add ssl certificate as a bundle of domain root cert, intermediate cert and root cert.


I have Very Simple Solution of this problem. You can do this without any certificate file..

Go on Laravel Root Folder -> Vender -> guzzlehttp -> guzzle -> src

open Client.php

find $defaults Array . that look like this way ..

$defaults = [
    'allow_redirects' => RedirectMiddleware::$defaultSettings,
    'http_errors'     => true,
    'decode_content'  => true,
    'verify'          => true,
    'cookies'         => false
];

Now main Job is to change value of verify key ..

'verify'          => false,

So After this it will not check SSL Certificate for CURL Request... This Solution is work for me. I find this solution after many research ...


I tried this it works

open

vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php

and change this

 $conf[CURLOPT_SSL_VERIFYHOST] = 2;
 `enter code here`$conf[CURLOPT_SSL_VERIFYPEER] = true;

to this

$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = FALSE;

The above steps, though helpful, didnt work for me on Windows 8. I don't know the co-relation, but the below steps worked. Basically a change in the cacert.pem file. Hope this helps someone.

  • Download cacert.pem file from here: http://curl.haxx.se/docs/caextract.html
  • Save the file in your PHP installation folder. (eg: If using xampp – save it in c:\Installation_Dir\xampp\php\cacert.pem).
  • Open your php.ini file and add these lines:
  • curl.cainfo=”C:\Installation_Dir\xampp\php\cacert.pem” openssl.cafile=”C:\Installation_Dir\xampp\php\cacert.pem”
  • Restart your Apache server and that should fix it (Simply stop and start the services as needed).

Another reason this error can occur is if a CA bundle has been removed from your system (and is no longer available in ca-certificates).

This is currently the situation with the GeoTrust Global CA which (among other things) is used to sign Apple's certificate for APNS used for Push Notifications.

Additional details can be found on the bug report here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962596

You can manually add the GeoTrust Global CA certificate on your machine as suggested by Carlos Alberto Lopez Perez:

wget --no-check-certificate -c https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.pem   \
&& mkdir /usr/local/share/ca-certificates/extra                                                                       \
&& mv GeoTrust_Global_CA.pem /usr/local/share/ca-certificates/extra/GeoTrust_Global_CA.crt                            \
&& update-ca-certificates

Thanks @Mladen Janjetovic,

Your suggestion worked for me in mac with ampps installed.

Copied: http://curl.haxx.se/ca/cacert.pem

To: /Applications/AMPPS/extra/etc/openssl/certs/cacert.pem

And updated php.ini with that path and restarted Apache:

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"
openssl.cafile="/Applications/AMPPS/extra/etc/openssl/certs/cacert.pem"

And applied same setting in windows AMPPS installation and it worked perfectly in it too.

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/Ampps/php/extras/ssl/cacert.pem"
openssl.cafile="C:/Ampps/php/extras/ssl/cacert.pem"

: Same for wamp.

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"
openssl.cafile="C:/wamp/bin/php/php5.6.16/extras/ssl/cacert.pem"

If you are looking for generating new SSL certificate using SAN for localhost, steps on this post worked for me on Centos 7 / Vagrant / Chrome Browser.


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to ssl

Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website A fatal error occurred while creating a TLS client credential. The internal error state is 10013 curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number How to install OpenSSL in windows 10? ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" "SSL certificate verify failed" using pip to install packages ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel "ssl module in Python is not available" when installing package with pip3

Examples related to curl

What is the incentive for curl to release the library for free? curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number Converting a POSTMAN request to Curl git clone error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 How to post raw body data with curl? Curl : connection refused How to use the curl command in PowerShell? Curl to return http status code along with the response How to install php-curl in Ubuntu 16.04 curl: (35) SSL connect error

Examples related to xampp

Xampp localhost/dashboard phpMyAdmin ERROR: mysqli_real_connect(): (HY000/1045): Access denied for user 'pma'@'localhost' (using password: NO) Is there way to use two PHP versions in XAMPP? Where to find htdocs in XAMPP Mac phpMyAdmin access denied for user 'root'@'localhost' (using password: NO) How to downgrade php from 7.1.1 to 5.6 in xampp 7.1.1? How to turn on/off MySQL strict mode in localhost (xampp)? mysqli_connect(): (HY000/2002): No connection could be made because the target machine actively refused it How to install mcrypt extension in xampp Fatal error: Uncaught Error: Call to undefined function mysql_connect()

Examples related to mandrill

PHP - SSL certificate error: unable to get local issuer certificate