Last updated on August 4th, 2026 at 03:44 pm
The main lesson: two PHP HTTP functions can call the same endpoint but wait for different lengths of time. A request that succeeds with file_get_contents() can still fail with wp_remote_get() when WordPress reaches its timeout first.
What I learned
A cURL error 28 does not automatically mean the endpoint is unavailable. It means the request did not finish before the configured time limit.
In the case I investigated, the WordPress request stopped after about five seconds. The PHP stream request had a longer timeout, so it had enough time to receive the response.
Use the WordPress HTTP API with an explicit timeout
The practical fix is to keep using the WordPress HTTP API and set a timeout that matches the expected response time.
$response = wp_remote_get($api_url, [
'timeout' => 30,
]);
if (is_wp_error($response)) {
error_log($response->get_error_message());
return false;
}
$status = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
if ($status < 200 || $status >= 300) {
error_log("API returned HTTP {$status}");
return false;
}
$data = json_decode($body, true);
This keeps WordPress error handling and response helpers while giving a slower endpoint more time.
A simple troubleshooting process
- Read the full error and note the elapsed time.
- Set an explicit
timeoutinwp_remote_get(). - Check for
WP_Errorbefore reading the body. - Validate the HTTP status code before decoding JSON.
- If it still fails, test whether the PHP runtime can reach the endpoint.
Common causes and fixes
- Cause: The endpoint needs longer than the default wait. Fix: Set a realistic explicit timeout.
- Cause: A local hostname means something different inside a container. Fix: use a hostname reachable from that runtime.
- Cause: Proxy settings or WordPress HTTP filters change the request. Fix: inspect those settings and filters.
- Cause: The code treats every response as successful. Fix: handle both
WP_Errorand non-2xx status codes.
Why not switch to file_get_contents()?
A longer implicit timeout can hide the real issue. WordPress’s HTTP API provides consistent error objects, response-code helpers, and integration with WordPress configuration. Setting the timeout explicitly makes the behavior clear and easier to debug.
Conclusion
When one HTTP function works and another times out, compare their timeout and network behavior before blaming the endpoint. The next action is simple: add an explicit timeout to the WordPress request and handle its error and status responses.
