Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GuzzleHttp Exception cURL error 60: SSL certificate problem: unable to get local issuer certificate #1935

Closed
gerryats opened this issue Oct 10, 2017 · 29 comments

Comments

@gerryats
Copy link

Hi, I am getting the SSL exception while uploading file to S3 , Strange thing is i have specified the certificate in the config/filesystems.php in s3 block but it still gives this error.
I tried uploading file to s3 using Curl command line it works fine with the cacerts which i am providing in the filesystem.

Any help will be greatly appreciated, I am not able to pin point the issue as curl command line able to upload file to s3.

Below is Stack Trace

GuzzleHttp\Exception\RequestException: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php:187
Stack trace:
#0 /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(150): GuzzleHttp\Handler\CurlFactory::createRejection(Object(GuzzleHttp\Handler\EasyHandle), Array)
#1 /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php(103): GuzzleHttp\Handler\CurlFactory::finishError(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#2 /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(179): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(108): GuzzleHttp\Handler\CurlMultiHandler->processMessages()
#4 /var/www/laravel/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(123): GuzzleHttp\Handler\CurlMultiHandler->tick()
#5 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#6 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#7 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#8 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#9 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(267): GuzzleHttp\Promise\Promise->waitIfPending()
#10 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#11 /var/www/laravel/vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#12 /var/www/laravel/vendor/aws/aws-sdk-php/src/S3/S3ClientTrait.php(33): GuzzleHttp\Promise\Promise->wait()
#13 /var/www/laravel/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php(583): Aws\S3\S3Client->upload('elevatecds', '4/mampleInitial...', Resource id #8, 'private', Array)
#14 /var/www/laravel/vendor/league/flysystem-aws-s3-v3/src/AwsS3Adapter.php(368): League\Flysystem\AwsS3v3\AwsS3Adapter->upload('4/mampleInitial...', Resource id #8, Object(League\Flysystem\Config))
#15 /var/www/laravel/vendor/league/flysystem/src/Filesystem.php(122): League\Flysystem\AwsS3v3\AwsS3Adapter->writeStream('4/mampleInitial...', Resource id #8, Object(League\Flysystem\Config))
#16 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php(132): League\Flysystem\Filesystem->putStream('4/mampleInitial...', Resource id #8, Object(League\Flysystem\Config))
#17 /var/www/laravel/app/Http/Controllers/WorkspacesController.php(621): Illuminate\Filesystem\FilesystemAdapter->put('4/mampleInitial...', Resource id #8, Array)
#18 [internal function]: App\Http\Controllers\WorkspacesController->uploadFile(Object(Illuminate\Http\Request))
#19 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(55): call_user_func_array(Array, Array)
#20 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(44): Illuminate\Routing\Controller->callAction('uploadFile', Array)
#21 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Route.php(203): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\WorkspacesController), 'uploadFile')
#22 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Route.php(160): Illuminate\Routing\Route->runController()
#23 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(572): Illuminate\Routing\Route->run()
#24 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Routing\Router->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#25 /var/www/laravel/app/Http/Middleware/Authenticate.php(27): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#26 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): App\Http\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure))
#27 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#28 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(65): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#29 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#30 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#31 /var/www/laravel/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#32 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#33 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#34 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#35 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#37 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#38 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#39 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#40 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(59): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#41 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#42 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#43 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#44 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(574): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#45 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(533): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#46 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php(511): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#47 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#48 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(30): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http{closure}(Object(Illuminate\Http\Request))
#49 /var/www/laravel/vendor/barryvdh/laravel-debugbar/src/Middleware/Debugbar.php(51): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#50 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Barryvdh\Debugbar\Middleware\Debugbar->handle(Object(Illuminate\Http\Request), Object(Closure))
#51 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#52 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#53 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#54 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline{closure}(Object(Illuminate\Http\Request))
#55 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\Routing\Pipeline->Illuminate\Routing{closure}(Object(Illuminate\Http\Request))
#56 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#57 /var/www/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#58 /var/www/laravel/public/index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#59 {main}

@gerryats
Copy link
Author

HI Any one else facing this issue with Laravel 5.4 while uploading file to S3. Kindly let me know.

Thanks in Advance.
Gerry

@sagikazarmark
Copy link
Member

Do you have any example code? Have you tried manually configure Guzzle? If so, Guzzle won't read your laravel settings, so you have to configure them in Guzzle as well.

If you use some sort of integration package (not sure what they are called in case of laravel: bundle, package, module, gem, etc) you should probably check if that one works fine.

@gerryats
Copy link
Author

Hi
Thanks @sagikazarmark , let me check the option in laravel to pass ssl certificates to guzzle to see if that works.

@djouuuuh
Copy link

djouuuuh commented Nov 10, 2017

I'm getting this error with Drupal 8.4.0 as well. But not every time...

php-error staging-4763 [10-Nov-2017 13:08:30 America/Toronto] Uncaught PHP Exception GuzzleHttp\Exception\RequestException: "cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)" at /mnt/www/html/d8esricanadastg/docroot/vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php line 187 request_id="v-27d895be-c642-11e7-9b17-22000a2a779e"

@pan-christensen
Copy link

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem
Add the following line to php.ini:
curl.cainfo="/path/to/downloaded/cacert.pem"

More info:
https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

@cbaconnier
Copy link

I had the same issue.
The solution provided by @pan-christensen did not work for me.
The website on which I was requesting in HTTPS was apparently using a custom(?) SSL certificate.

So, I opened the certificates in chrome and exported all (3) certificates I could: see screenshot
and added them to a custom mycertfile.pem

Then using it with Guzzle this way:
$client = new Client(['verify' => '/my/path/to/mycertfile.pem']);

Now it's working!

You can also download a certificate with the openssl command, but I my case it wasn't the right certificate. So I had to download them manually

@sagikazarmark
Copy link
Member

You probably want to contact the website owner, as using a self-signed cert and trusting it without verification from the owner is not a good idea. That cert you downloaded could already be part of a man-in-the-middle attach.

@sushengbuhuo
Copy link

@pan-christensen it is right

@DIMITA
Copy link

DIMITA commented Mar 24, 2019

i have a similare error with kreait of firebase but i use one by one your response but i can't resolve my problem
i configure openssl on my local server
use curl config in php.ini

            $serviceAccount = ServiceAccount::fromJsonFile(__DIR__.'/firebaseKey.json');
            $firebase = (new Factory)
                ->withServiceAccount($serviceAccount)
                ->create();
    
            $database = $firebase->getDatabase();
            $ref = $database->getReference('Test');
    
            $key = $ref->push()->getKey();
    
            var_dump(openssl_get_cert_locations());
            return $key;

@AsmaGargouri
Copy link

Solution of @pan-christensen worked for me.

@kumirska
Copy link

kumirska commented Nov 6, 2019

in my case, the file descriptors just ran out

@leonelngande
Copy link

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem
Add the following line to php.ini:
curl.cainfo="/path/to/downloaded/cacert.pem"

More info:
https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

If you're on Windows and still getting the error after applying the above, make sure you're updating the correct php.ini file.

Run php -i | grep php.ini to print out the path the the ini configuration in use. Have been trying to fix this since last night and turns out I was editing the wrong ini file, smh.

@sbonline
Copy link

It might not be client problem at all. for me it was the backend.

Check your certificate chain.

In my case it was simply wrong intermediate certificate. (the browser downloaded the extra cert silently, but SSLLABS shows me the extra download issue)

@virgilshelton
Copy link

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem
Add the following line to php.ini:
curl.cainfo="/path/to/downloaded/cacert.pem"
More info:
https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

If you're on Windows and still getting the error after applying the above, make sure you're updating the correct php.ini file.

Run php -i | grep php.ini to print out the path the the ini configuration in use. Have been trying to fix this since last night and turns out I was editing the wrong ini file, smh.

Thanks for the fix, I was editing the wrong php.ini running WAMP :)

@EdisonValdez
Copy link

@virgilshelton Thanks it worked great!

@chaaawles
Copy link

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem
Add the following line to php.ini:
curl.cainfo="/path/to/downloaded/cacert.pem"

More info:
https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

does anyone knows how to do this in hostinger or hostgator?

@Ishodnikov
Copy link

Ishodnikov commented May 15, 2020

$client = new \GuzzleHttp\Client(['verify' => false ]);

@gmponos
Copy link
Member

gmponos commented May 20, 2020

Hi here.. there is an FAQ section in docs for this

http://docs.guzzlephp.org/en/stable/faq.html#why-am-i-getting-an-ssl-verification-error

Many solutions have been given to this post. Please note that setting verify to false as stated in the docs it is considered insecure.

@gmponos gmponos closed this as completed May 20, 2020
@ravimisra
Copy link

I had the same issue.
The solution provided by @pan-christensen did not work for me.
The website on which I was requesting in HTTPS was apparently using a custom(?) SSL certificate.

So, I opened the certificates in chrome and exported all (3) certificates I could: see screenshot
and added them to a custom mycertfile.pem

Then using it with Guzzle this way:
$client = new Client(['verify' => '/my/path/to/mycertfile.pem']);

Now it's working!

You can also download a certificate with the openssl command, but I my case it wasn't the right certificate. So I had to download them manually

A similar issue was with me, our site is using our own SSL certificate issued by a signing authority. Though it was still valid, one of the intermediate signing authority certificate in the chained bundle was expired. Replacing that certificate in the bundle resolved the issue.

@irushabhthakar
Copy link

$client = new \GuzzleHttp\Client(['verify' => false ]);

Thank you :)

@marthanash
Copy link

for laravel 7 use
$response = Http::withoutVerifying()->post('https://www.testwebsite.com')

@mamadou330
Copy link

HI Toute autre personne confrontée à ce problème avec Laravel 5.4 lors du téléchargement du fichier sur S3. Veuillez me le faire savoir.

Merci d'avance.
Gerry

salut mon grand moi j'ai un probleme de ce genre sur curl error 60:ssl

@Crumor
Copy link

Crumor commented Oct 6, 2021

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem Add the following line to php.ini: curl.cainfo="/path/to/downloaded/cacert.pem"

More info: https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

awesome, works like charm

@AdamRatcliffeDeetu
Copy link

Download the latest cacert.pem from https://curl.haxx.se/ca/cacert.pem Add the following line to php.ini: curl.cainfo="/path/to/downloaded/cacert.pem"

More info: https://stackoverflow.com/questions/24611640/curl-60-ssl-certificate-unable-to-get-local-issuer-certificate

Hi I've been experiencing a similar issue when trying to implement https://github.com/matthewbdaly/laravel-azure-storage/issues. I've tried to follow the instructions on my Wamp Server and changed the line in the php.ini to

curl.cainfo="C:\wamp64\bin\php\php7.3.12\extras\ssl\cacert.pem"

and then restarted my server but unfortunately the error still occurs. Any help would be greatly appreciated.

@Sebi2020
Copy link

In windows the error persists. Even after setting curl.cainfo in the right php.ini...

@NawrasBukhari
Copy link

Any solution so far for hostinger? or and shared hosting provider

@tcpdump-examples
Copy link

The error message “curl: (60) SSL certificate problem: unable to get local issuer certificate” typically indicates a problem with the certificate of the server you’re trying to connect to or the certificate chain leading up to a trusted certificate authority.

It also checks if the server’s certificate is signed by a trusted certificate authority (CA). If the server’s certificate isn’t signed by a trusted CA, or if curl can’t find the CA in its list, you’ll see the error message you provided.

This article is pretty comprehensive. 4 ways to check curl: (60) SSL certificate problem: unable to get local issuer certificate

@legaciespanda
Copy link

legaciespanda commented Feb 7, 2024

ULTIMATE SOLUTION FOR WAMP AND XAMP USERS FOR WINDOWS 8,10,11+

PART 1

  1. Download https://curl.haxx.se/ca/cacert.pem

  2. After download, move this file to your wamp server.
    For exp: C:\wamp64\bin\php\php8.2.0\extras\ssl

  3. Search and uncomment the curl.cainfo in php.ini file located here (php folder)
    C:\wamp64\bin\php\php8.2.0

curl.cainfo="C:\wamp64\bin\php\php8.2.0\extras\ssl\cacert.pem"

PART 2

  1. Search and uncomment the curl.cainfo in php.ini file located here (apache bin folder)
    C:\wamp64\bin\apache\apache2.4.54.2\bin

curl.cainfo="C:\wamp64\bin\php\php8.2.0\extras\ssl\cacert.pem"

Now restart your wamp server.

NOTE: change php version and apache version to yours

@xasz
Copy link

xasz commented Feb 7, 2024

For IIS you simply do Part 1 of @legaciespanda solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests