DevKinsta Localhost: cURL error 60: SSL certificate problem

For future readers, please note that the issue discussed here is not a critical problem; it’s primarily an annoyance. However, if you’re interested in resolving it, here’s an explanation.

The issue arises when you enable HTTPS locally; DevKinsta utilizes a self-signed certificate. CURL, which verifies certificates, uses a bundle that contains public keys from recognized certificate authorities. Naturally, a self-signed certificate isn’t recognized by this bundle. Consequently, when a plugin or your code uses CURL to fetch data from your own page (e.g., https://your-site.local), you will encounter the SSL error 60.

In my efforts to resolve this, I discovered that you need to add your own certificate to the certificate bundle used by CURL. This adjustment is made inside the devkinsta_fpm container. Unfortunately, this didn’t solve my issue entirely. It turns out that wp_remote_get(), a PHP function within WordPress, uses its own set of certificates. To address the problem, you must add your certificate to the bundle located at wp-includes/certificates/ca-bundle.crt. Simply open this file in a text editor to make the addition.

Disclaimer: This is not inherently a problem; it’s more about alleviating an annoyance. I’m not aware of all potential consequences of these changes. For instance, they might be overwritten during a WordPress update, or they might complicate collaboration in a team setting. I just wanted to shed some light on this. Below is a PHP script you can use to test for these errors by adding the script to your plugin folder:

/**
 * Plugin Name: CURL and WP Remote Get Test Plugin
 * Description: Tests CURL requests and WordPress HTTP API requests from the admin area.
 * Version: 1.0
 * Author: ChatGPT4
 */

function curl_and_wp_remote_test_menu() {
    add_menu_page('CURL and WP Remote Test', 'CURL and WP Remote Test', 'manage_options', 'curl_wp_remote_test_plugin', 'curl_wp_remote_test_admin_page');
}

add_action('admin_menu', 'curl_and_wp_remote_test_menu');

function curl_wp_remote_test_admin_page() {
    echo '<h2>CURL and WP Remote Get Test Output</h2>';

    // CURL Test
    $curl_url = 'https://your-site.local'; // Adjust the URL to match your needs
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $curl_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); // This ensures SSL verification is enabled
    $output = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);

    if (!empty($error)) {
        echo "<p>CURL Error: " . esc_html($error) . "</p>";
    } else {
        echo "<p>Success: CURL fetched the CSS file successfully.</p>";
    }

    // WordPress HTTP API Test
    $wp_remote_url = 'https://your-site.local'; // Change this to a URL with your self-signed certificate
    $response = wp_remote_get($wp_remote_url, array('sslverify' => true));

    if (is_wp_error($response)) {
        echo '<div class="notice notice-error"><p>WP Remote Get Test Failed: ' . esc_html($response->get_error_message()) . '</p></div>';
    } else {
        echo '<div class="notice notice-success"><p>WP Remote Get Test Succeeded: Response successfully received.</p></div>';
    }
}
1 Like