So I burned up a good part of the morning digging into the specific error I saw when I reported this. Here is what I found. Maybe it will help you, or others, or not. I don’t know, but I do know that CleanTalk appears to have looked for non-existent file. At least in this particular instance.
I’ve set up a cron job on my server to make certain the requested file is in place, but that shouldn’t be necessary since it’s not part of core. If there are further errors I will attempt to figure them as well.
I’ve whitelisted the IPs on my server, too. That doesn’t seem to have been the issue, though.
Here is the full report:
# Report: CleanTalk License Key Deactivation Caused by Missing WordPress Core File (cURL Error 77)
**Server environment:** Dedicated server, CloudLinux 8 + EasyApache4 (cPanel), ~70+ WordPress sites
**Date:** August 4, 2026
## Summary
Multiple WordPress sites on our server had their CleanTalk license keys deactivate at various times. At least in this case, it exposed an underlying error, unrelated to CleanTalk's servers or the license itself. This report documents the root cause and includes a request for a plugin-side improvement.
## The Error
<br>Error occurred while checking account status. cURL error 77: error adding trust anchors from<br>locations: CAfile: /home/[account]/public_html/wp-includes/Requests/src/../certificates/cacert.pem<br>CApath: none<br>
## Root Cause
WordPress core's bundled HTTP library (WpOrg\Requests) points cURL's SSL certificate verification at a local file: wp-includes/Requests/certificates/cacert.pem. This file was missing on affected sites.
We confirmed via wp core verify-checksums that this file is **not part of WordPress.org's official checksum manifest** for the installed core version — meaning it was never delivered as part of the WordPress core package these sites were built from, rather than being deleted or corrupted after the fact.
Because the omission was present at provisioning time, it affected every site sharing that WordPress core build — in our case, **80 of ~81 WordPress installations on the server**.
## Why This Points to CleanTalk's Request Handling
WordPress's standard HTTP API (wp_remote_get() / wp_remote_post(), via WP_Http::request()) does **not** rely on the file that was missing. It explicitly sets its own default CA certificate path on every request:
<br>'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt'<br>
That file (wp-includes/certificates/ca-bundle.crt) **is** part of the official WordPress core package, and **is** kept current automatically on every core update. We confirmed it was present and current on the affected site the entire time.
The file that was actually missing — wp-includes/Requests/certificates/cacert.pem — is only consulted by the underlying WpOrg\Requests library as an internal fallback default, and only when a caller does not supply its own certificate path. Under a standard wp_remote_get()/wp_remote_post() call, that fallback should never be reached, because WordPress always supplies its own path first.
This suggests CleanTalk's account/key status check is not going through WordPress's standard HTTP API in the normal way — either by calling the WpOrg\Requests library directly, or by filtering http_request_args in a way that strips the sslcertificates option — causing it to fall through to a Requests-library-internal path that is not part of WordPress's official, auto-maintained certificate handling. In other words, a working, current CA bundle was available and used by every other plugin on these sites; CleanTalk's status check appears to be the one request path that missed it.
## Impact on CleanTalk
The missing fallback file caused cURL to fail immediately with error 77 (a local file/config problem, not an actual SSL trust failure or invalid key) whenever CleanTalk's status check ran. CleanTalk's plugin appears to interpret this failed status check as grounds to deactivate the license key.
## Our Fix
We restored the missing file from the curl project's official CA bundle (https://curl.se/ca/cacert.pem) on all affected accounts and added a monitoring script to catch recurrence on future site provisions.
## A Note on the "Intermittent" Pattern
The missing file was present on all affected sites simultaneously and deterministically caused every status check to fail — it was not intermittent at the root-cause level. The scattered/random-looking deactivation pattern across sites is better explained by CleanTalk's status check running on its own interval or cache per site (cron, transient, or an admin-triggered check), rather than on every page load. Each site simply failed on its own separate schedule as its next check came due. This supports the conclusion that the underlying design issue — deactivating a key on a transport-level failure — is systemic, not a handful of isolated incidents.
## Scope of This Report
To be clear about what we're claiming: we have directly confirmed this failure mode on our own server — the missing file, the resulting cURL error, and its correlation with key deactivation. We do not have visibility into other users' servers or logs, so we can't confirm this is the cause of every deactivation others have reported. What we can say is that this is a real, verifiable, reproducible failure mode that would produce exactly the symptom other users are describing, and it's worth ruling in or out on any account experiencing similar unexplained deactivations.
## Request to CleanTalk
The missing-file condition itself is a hosting/WordPress-core packaging issue outside CleanTalk's control. However, based on other users reporting similar unexplained key deactivations, we believe your plugin's status-check logic may be treating a **local SSL/cURL error** (a client-side problem reaching your servers) the same as an **invalid or unauthorized key** (an actual license problem). These are different failure modes and arguably should be handled differently:
- Consider distinguishing connection/transport errors (cURL errors, timeouts, DNS failures) from an explicit "key invalid" response from your API, and avoid deactivating the key on the former.
- Consider a retry/backoff before deactivation, rather than deactivating on a single failed check.
- Consider surfacing the actual error (e.g., "cURL error 77...") in the plugin's admin notice when a status check fails, rather than a generic deactivation message — this would have saved significant diagnostic time and would help other admins self-diagnose the same issue.
-
This reply was modified 5 days, 22 hours ago by
netpotion.