Support » Localhost Installs » cURL error 28 on localhost updates

  • Resolved kontur

    (@kontur)


    Hey,

    since I recently updated my PHP version to 7.2 on my local machine all vhosts’s cURL updates fail, but I am stuck with what else to try debug.

    PHP is installed via brew on my Mac. I initially suspected a cURL version problem, because many similar help topics refer to this. However, I think my cURL should be okay.

    In the Health Check plugin I get:

    Site Status

    WordPress Version 	
    Plugin Versions 	
    
        Your site has 18 active plugins, and they are all up to date.
        Your site has 32 inactive plugins, it is recommended to remove any unused plugins to enhance your site security.
    
    Theme Versions 	
    
        Your site has 10 installed themes, and they are all up to date.
        Your site has 8 inactive themes, other than twentynineteen, the default WordPress theme, and , your active theme. It is recommended to remove any unused themes to enhance your sites security.
    
    PHP Version 	7.2.15
    Database Server version 	5.6.20
    PHP Extensions 	
    
        The optional module, imagick, is not installer, or has been disabled.
    
    MySQL utf8mb4 support 	Your MySQL version supports utf8mb4
    HTTPS status 	You are accessing this website using HTTPS.
    Secure communication 	Your WordPress install can communicate securely with other services.
    Scheduled events 	A scheduled event (action_scheduler_run_queue) has failed to run. Your site still works, but this may indicate that scheduling posts or automated updates may not work as intended.
    Plugin and Theme Updates 	
    
        Plugin updates should be working as expected.
        Theme updates should be working as expected.
    
    HTTP Requests 	HTTP requests should be working as expected.
    REST API availability 	The REST API request failed due to an error.
    Error encountered: (0) cURL error 28: Resolving timed out after 10074 milliseconds
    Communication with WordPress.org 	Unable to reach WordPress.org at 198.143.164.252: cURL error 28: Resolving timed out after 10074 milliseconds
    Background updates 	
    
        A plugin has prevented updates by disabling wp_version_check().
        No version control systems were detected.
        Your installation of WordPress doesn't require FTP credentials to perform updates.
    
    Loopback request 	The loopback request to your site failed, this may prevent WP_Cron from working, along with theme and plugin editors.
    Error encountered: (0) cURL error 28: Resolving timed out after 10069 milliseconds

    And in the PHP information tab, cURL section:

    cURL support 	enabled
    cURL Information 	7.64.0
    Age 	4
    Features
    AsynchDNS 	Yes
    CharConv 	No
    Debug 	No
    GSS-Negotiate 	No
    IDN 	No
    IPv6 	Yes
    krb4 	No
    Largefile 	Yes
    libz 	Yes
    NTLM 	Yes
    NTLMWB 	Yes
    SPNEGO 	Yes
    SSL 	Yes
    SSPI 	No
    TLS-SRP 	Yes
    HTTP2 	Yes
    GSSAPI 	Yes
    KERBEROS5 	Yes
    UNIX_SOCKETS 	Yes
    PSL 	No
    Protocols 	dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, ldaps, pop3, pop3s, rtmp, rtsp, scp, sftp, smb, smbs, smtp, smtps, telnet, tftp
    Host 	x86_64-apple-darwin18.2.0
    SSL Version 	OpenSSL/1.0.2q
    ZLib Version 	1.2.11
    libSSH Version 	libssh2/1.8.0 

    I have this problem both on local sites that I have a local self-signed certificate as well as non-https local sites.

    I’ve tried manually setting up a cURL request to see the response, for example in my theme functions.php, and for this code:

    $ch = curl_init("http://api.wordpress.org/core/version-check/1.7/");
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    var_dump("error", curl_error($ch));
    curl_close($ch);

    I get this response: string(5) "error" string(0) ""

    At this point I don’t know any more what else to try to debug this any further. Suggestions?

Viewing 15 replies - 1 through 15 (of 15 total)
  • Hello,

    Try installing this plugin and see if it returns an error.

    https://wordpress.org/plugins/php-compatibility-checker/

    We might find a way to move ahead.

    Thanks.

    kontur

    (@kontur)

    That plugin does not return anything. When I install it, disable all other plugins, press the check button nothing happens on the page, but the JSON response seems to be this:

    status	false
    count	0
    total	false
    activeJob	false
    version	false
    onlyActive	false
    results	false

    Since the AJAX call will trigger the same automatic update that fails, the returned JSON response might be compromised and thus not displaying correctly. I’ve set my php error logging and wp-config error logging, though, and am not seeing errors.

    Also, the plugin says: “The scan will get stuck if WP-Cron is not running correctly. Please see the FAQ for more information.” As per my above info, CRONs are not running correctly.

    • This reply was modified 4 months ago by  kontur.
    Dion Designs

    (@diondesigns)

    Your sample curl code does not work because you didn’t call curl_exec() to execute the request.

    What do you see if you go to the command line and run the following command:

    curl -v http://api.wordpress.org/core/version-check/1.7/
    

    You should see the request and response headers, followed by a JSON-encoded string. If you don’t see this, then the issue is your version of curl (or possibly network-related). If you see the expected result, then check your PHP error log to see if there are any problems reported.

    While at the command line, also run the following command:

    php -r "echo file_get_contents('http://api.wordpress.org/core/version-check/1.7/');"
    

    Assuming allow_url_fopen is enabled in PHP (and it should be enabled), this should also return the JSON-encoded string. If you see anything else, or if the command doesn’t execute after 60 seconds, then either there is an issue with the build of PHP, or you have a network-related problem in your system.

    kontur

    (@kontur)

    You’re basically right about curl_exec() — only it works; I had just accidentally removed that line when copying my code here, because I var_dump()’d the result and remove most var_dump’s to clarify.

    Both the curl and php request return the expected JSON with update offers, which is also the result of my manually coded curl code:

    {"offers":[{"response":"upgrade","download":"http:\/\/downloads.wordpress.org\/release\/wordpress-5.1.zip","locale":"en_US","packages":{"full":"http:\/\/downloads.wordpress.org\/release\/wordpress-5.1.zip","no_content":"http:\/\/downloads.wordpress.org\/release\/wordpress-5.1-no-content.zip","new_bundled":"http:\/\/downloads.wordpress.org\/release\/wordpress-5.1-new-bundled.zip","partial":false,"rollback":false},"current":"5.1","version":"5.1","php_version":"5.2.4","mysql_version":"5.0","new_bundled":"5.0","partial_version":false}],"translations":[]}

    Only when the update check runs in the wp-admin area or via the WP CLI do I get the ever recurring:

    Warning: An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums. (WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.) in /Users/…/wp-includes/update.php on line 581

    I’ve also gone into the update.php and tried add a few debug traces where the call fails, but I haven’t found a way to output the exact request WP is performing. The particular error above is on a localhost with https setup, but I also get them on non-https localhost setups. When I hook into the class.http’s http_api_debug-hook I get these:

    object(WP_Error)#14580 (2) { ["errors"]=> array(1) { ["http_request_failed"]=> array(1) { [0]=> string(58) "cURL error 28: Resolving timed out after 5073 milliseconds" } } ["error_data"]=> array(0) { } } string(8) "response" string(8) "Requests" array(18) { ["method"]=> string(4) "POST" ["timeout"]=> int(5) ["redirection"]=> int(5) ["httpversion"]=> string(3) "1.0" ["user-agent"]=> string(49) "WordPress/5.1-RC1-44737; https://underscore.test/" ["reject_unsafe_urls"]=> bool(false) ["blocking"]=> bool(true) ["headers"]=> array(0) { } ["cookies"]=> array(0) { } ["body"]=> array(1) { ["useragent"]=> string(82) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:65.0) Gecko/20100101 Firefox/65.0" } ["compress"]=> bool(false) ["decompress"]=> bool(true) ["sslverify"]=> bool(true) ["sslcertificates"]=> string(77) "/Users/…/wp-includes/certificates/ca-bundle.crt" ["stream"]=> bool(false) ["filename"]=> NULL ["limit_response_size"]=> NULL ["_redirection"]=> int(5) }

    Again, this seems to not give me any more info than it’s a cURL 28 error.

    How can it be my self written cURL PHP code works but WP’s http requests fail? Is there a way to see exactly what cURL params WP uses?

    Since the minimal PHP cURL in my functions.php works, but WP’s fail, I tried to debug the WP cURL in /wp-includes/Requests/Transport/cURL.php — essentially I’ve tried to one by one disable as many curl_setopt as possible, and even with basically only the URL setter active I still get cURL timeout error codes.

    Also overwriting the timeout value has no effect on the problem, it just times out at different intervals.

    Try restarting your webserver, and if you’re using PHP-FPM, restart that as well. Then check the PHP and webserver error logs to see if they report a libcurl version mismatch. If one of them does, then you’ll need to re-apply the PHP update so it binds with the correct version of libcurl on your system, and then restart the webserver/PHP afterwards.

    Otherwise I’m out of ideas. Good luck!

    (I hope the mods remove the spam “personal suggestion” link above, and then look at the dude’s profile to see that it’s been going on for a while…)

    Thanks for the suggestions. I don’t believe I am using PHP-FPM. Error logs don’t show anything; in the httpd logs I only have the occasional log about directory permissions grant settings, in the PHP logs I only have actual PHP errors and warnings from code.

    Agree with you, Fahim’s suggestion is off topic.

    More digging has revealed that it’s not an issue with the CURLOPT_TIMEOUT but with CURLOPT_CONNECTTIMEOUT, actually!

    Increasing the CURLOPT_CONNECTTIMEOUT the request go through. The problem is a) I don’t know what changed in my PHP upgrade that the behavior in this regard is different now, and b) I don’t know how to set this aside from the http_api_curl — for example my WP CLI calls still fail, because they use the 10s default defined in /wp-includes/class-request.php.

    So far I have not found anything in php.ini that would influence this, and it’s not setable via any global outside of the specific handle either.

    Any ideas?

    That’s really interesting…is it possible that PHP changed the default for CURLOPT_CONNECTTIMEOUT without documenting it? I also looked at the WP code that sets up curl-based requests and found the following in wp-includes/class-wp-http-curl.php:

    $timeout = (int) ceil( $r['timeout'] );
    curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, $timeout );
    curl_setopt( $handle, CURLOPT_TIMEOUT, $timeout );

    Here is the curl documentation for the two options:

    https://curl.haxx.se/libcurl/c/CURLOPT_CONNECTTIMEOUT.html
    https://curl.haxx.se/libcurl/c/CURLOPT_TIMEOUT.html

    They are very different options, and setting them to be the same value would appear to be a bad idea. (It would explain why some people have issues with updates or installing new themes/plugins from their listings.) However, there is a http_api_curl action hook that should allow you to set/change the curl options. The docs say that it’s meant for cookies, but since the curl handle is passed, it can be used to reset CURLOPT_CONNECTTIMEOUT.

    https://developer.wordpress.org/reference/hooks/http_api_curl/

    Yes, correct. I use:

    add_filter('http_api_curl', 'custom_curling', 10, 3);
    function custom_curling($handle, $r, $url) {
    	curl_setopt($handle, CURLOPT_CONNECTTIMEOUT_MS, 60000);
    	return $handle;
    }

    in functions.php to at least get the back end to load without all the failing cURL calls. However this is not a solution. a) I’d have to do this to all localhost projects (10~20 at any given time) and b) it does not apply to WP CLI for example.

    Also asked on Stackoverflow and Stackoverflow.

    The more I look at this, the more I think this is a bug in WordPress. Resetting CURLOPT_CONNECTTIMEOUT from its default of 300s to 10s is going to cause issues on some sites. Perhaps the default 300s should be restored. Perhaps it could honor a settable constant (let’s call it WP_CURL_CONNECTTIMEOUT), and then use something else if the constant does not exist.

    It might be worth heading over to core.trac.wordpress.org and submitting a ticket. I checked the current tickets and didn’t see this reported:

    https://core.trac.wordpress.org/component/HTTP%20API

    The 10s comes from a method setting defaults on the request. Checking for a recent change in that is appears that same default has been in place for 3 years, so I doubt this issue is introduced from WP side. However, it might be PHP has changed some handling, or that, simply, something on my php/httpd config locally is off, which is most likely the case — but I have no clue what.

    I find it also curious that a simple cURL on the terminal just executes (that is, connects, and transfers) right away, while establishing the cURL from within WP takes more than 10s to establish in the first place.

    In the meantime I have also found and made use of CURLOPT_VERBOSE which I set in WP’s /wp-includes/Request/Transports/curl.php right before the curl_exec() and logged the output to a file. It looks something like this:

    * Expire in 0 ms for 6 (transfer 0x7fa77e02a600)
    * Expire in 30000 ms for 8 (transfer 0x7fa77e02a600)
    * Expire in 10000 ms for 2 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2852 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2852 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2852 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1781 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1781 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1781 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 707 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 707 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 707 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 5000 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 3926 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2857 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2856 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 2856 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1783 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1783 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 1783 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 710 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 710 ms for 1 (transfer 0x7fa77e02a600)
    * Expire in 710 ms for 1 (transfer 0x7fa77e02a600)
    * Resolving timed out after 10071 milliseconds
    * Closing connection 0

    As you can see there is some “odd” bumps and jumps, and the 10000ms timeout that eventually breaks the cURL call.

    Again, I don’t understand what can cause this connecting delay — could this be some limit on concurrency of cURL calls or something like that? Or that some WP internal cURL call takes very long due to some misconfiguration on my local server, requesting something that endlessly redirects or something like that, and then break subsequent cURL calls? Really puzzling…

    Any help with this appreciated very much still.

    Please can someone ELI5 (explain like I’m five) how to fix this error. I’m getting it when I try to add my API token to Mailchimp.

    [Mailchimp says: API Request Error – cURL error 28: Operation timed out after 60001 milliseconds with 0 bytes received]

    TIA

    This was solved by updating and explicitly setting other than my ISP provided DNS servers in my MacOS system network settings. I used DNS servers 8.8.8.8 and 8.8.8.4 (Google’s) and now the cURL requests resolve right away no longer causing the timeout.

    I still can’t tell what about those WP cURLs is different from other requests that they would timeout on DNS resolve, but other explicitly coded cURL or curl on CLI would not do the same, but alas.

    @jacsify I am not sure if your case is exactly the same or if that applies to your problem. You might want to open your own topic and provide more information. Localhost or server? Only mailchimp plugin? Etc.

Viewing 15 replies - 1 through 15 (of 15 total)
  • You must be logged in to reply to this topic.