Services built by a real sysadmin.

Every product in this shop was tested in production, optimized under pressure, and designed to make your infrastructure safer, faster, and cleaner.

Browse services

Fix Loopback, Action-Scheduler past-due actions and REST API 403 Errors on WordPress Behind Cloudflare

cloudflare-403-rest-loopback-api-wordpress

If your WordPress site is behind Cloudflare, you may run into issues where WP-Cron, loopback requests, or the REST API stop working properly. This typically happens because Cloudflare blocks server-to-server requests from your own domain due to bot protection, JavaScript challenges, or rate limiting.


The Problem

WordPress internally calls its own URLs (like wp-cron.php or REST API endpoints) using HTTP requests. When your domain is protected by Cloudflare, those internal requests may get blocked with a 403 Forbidden response — even though everything works fine for real visitors.

This breaks important features like:

  • Cron jobs (DISABLE_WP_CRON or background tasks)
  • Plugin updates and checks
  • Site Health REST API tests
  • Some block editor functionality

What You See in Site Health

Under Tools > Site Health, you may encounter this warning:

The REST API encountered an unexpected result

The REST API is one way that WordPress and other applications communicate with the server. For example, the block editor screen relies on the REST API to display and save your posts and pages.

REST API Endpoint: https://your-site.com/wp-json/wp/v2/types/post?context=edit
REST API Response: (403) Forbidden

Action Scheduler may show this notice:

Action Scheduler: 31 past-due actions found; something may be wrong. Read documentation

You may also see that WP-Cron or plugin update checks silently fail, especially if you’re using Cloudflare Bot Fight Mode or JS Challenge settings.


The Solution: Bypass DNS and Use Direct IP with Host Header

To fix this, we can intercept all outgoing HTTP requests from WordPress that go to your-site.com and force them to use the direct IP address, while still sending the proper Host header (your-site.com).

🛠 Add This Code to Your functions.php

add_action( 'http_api_curl', function( $handle, $r, $url ) {
    if ( strpos( $url, 'your-site.com' ) !== false ) {
        // Host header
        curl_setopt( $handle, CURLOPT_HTTPHEADER, array(
            'Host: your-site.com'
        ) );

        // Override URL to use direct IP
        $ip = '167.253.159.232';
        $new_url = str_replace( 'your-site.com', $ip, $url );
        curl_setopt( $handle, CURLOPT_URL, $new_url );

        // Optional: skip SSL verification if HTTPS
        curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, false );
        curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, false );
    }
}, 10, 3 );

🧠 Why It Works

  • WordPress core uses wp_remote_get() and similar functions to communicate with itself.
  • Normally, those requests resolve the domain via DNS — which goes through Cloudflare.
  • With this hook, we force the request to use the real server IP, bypassing Cloudflare.
  • The Host header ensures that WordPress still treats the request as coming to your-site.com.

Summary

If you’re getting 403 Forbidden errors when WordPress tries to call itself (for cron jobs, REST API, or updates), and your site is behind Cloudflare, this trick forces internal requests to talk directly to the origin server.

No more Cloudflare blockages. Just clean internal communication, like it should be.

Need Expert Help?

If you’re still having issues with your server or network setup, let’s fix it together. Schedule a one-on-one consultation now.

Schedule a Consultation

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *