Common causes
- PHP on Windows (XAMPP, WAMP, Laragon) has no CA bundle configured in curl.cainfo or openssl.cafile
- An outdated ca-certificates package on an old Linux server that lacks newer root certificates
- The remote server sends only its leaf certificate without the intermediate chain (use fullchain.pem, not cert.pem)
- A corporate proxy or antivirus intercepts HTTPS with its own root certificate that PHP does not trust
- The remote certificate is self-signed or expired
- A Docker image built without the ca-certificates package
How to fix it
- Find which side is wrong. Check the remote site with an SSL checker or openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts. If the chain is incomplete there, the remote server must fix it; if it is complete, your client's CA bundle is the problem.
- Update the system CA bundle (Linux). Run sudo apt update && sudo apt install --reinstall ca-certificates (Debian/Ubuntu) or sudo dnf update ca-certificates (RHEL), or add apk add ca-certificates in Alpine Docker images.
- Set curl.cainfo in php.ini (Windows/local). Download the current cacert.pem from the curl website, save it to a stable path, and set curl.cainfo and openssl.cafile to that path in the php.ini used by your PHP (check with php --ini). Restart Apache or PHP-FPM.
- Fix the chain on your own server. If the failing URL is your own site, configure the web server with the full chain (fullchain.pem or the CA bundle file) instead of just the certificate.
- Trust a corporate root properly. If a company proxy intercepts traffic, add its root certificate to the system trust store and update-ca-certificates rather than disabling verification.
- Never disable verification. Setting CURLOPT_SSL_VERIFYPEER to false or 'verify' => false in Guzzle makes the error go away by removing protection against man-in-the-middle attacks. Do not use it in production.
php.ini (Windows / local dev)
[curl]
curl.cainfo = "C:\php\extras\ssl\cacert.pem"
[openssl]
openssl.cafile = "C:\php\extras\ssl\cacert.pem"
; Linux: sudo apt install --reinstall ca-certificates How to stop it happening again
- Keep ca-certificates updated as part of normal OS updates
- Include ca-certificates in every Docker base image
- Always serve fullchain certificates on your own servers