Site Health REST API and Loopback Errors
How to diagnose WordPress Site Health warnings about the REST API or loopback requests: they are usually caused by a plugin or snippet, not the firewall.
Updated August 2026
WordPress Site Health (“Salud del sitio” in Spanish installs) sometimes reports that the REST API encountered an error or that loopback requests are failing, often alongside a broken block editor or 404 errors in the browser console. The first suspicion is usually a firewall or security rule on the server. In our experience it almost never is: the most common cause is a security plugin or code snippet on the site itself.
Step 1: confirm the REST API works from outside
Run this from any computer (or an online HTTP tester), replacing the domain:
curl -i "https://example.com/wp-json/wp/v2/types/post"
- HTTP 200 with JSON: the REST API is reachable and the web server, firewall, and WAF are passing it. The problem is inside WordPress: continue below.
- HTTP 403 or a block page: only then is a server-side rule involved: open a support ticket with the exact output and we will check the WAF logs.
Step 2: find the exact failing request
Site Health’s warnings are generic; the browser knows the specific request that failed:
- Open Tools → Site Health in wp-admin.
- Press F12 to open the browser developer tools and select the Network tab.
- Reload the page and look for requests shown in red.
- Note the URL and the status code of each failing request.
A very frequent finding is 404 on /wp-json/wp/v2/users/me. wp-admin loads this route on every page (the block editor and the preferences system depend on it), so anything that removes the users routes breaks the admin in subtle ways.
The usual culprit: a snippet that deletes REST routes
A popular “hide user enumeration” hardening recipe removes the users endpoints entirely:
// PROBLEM: this breaks wp-admin, Site Health, and any integration
// that needs /wp/v2/users, including for logged-in administrators.
add_filter( 'rest_endpoints', function ( $endpoints ) {
foreach ( $endpoints as $route => $handler ) {
if ( strpos( $route, '/wp/v2/users' ) === 0 ) {
unset( $endpoints[ $route ] );
}
}
return $endpoints;
} );
Look for it in the Code Snippets plugin, the theme’s functions.php, a custom plugin, or the “hide my site” section of security plugins (many have an equivalent toggle such as “disable REST API users endpoint”).
The safe version blocks only anonymous visitors and keeps the routes working for logged-in users, so wp-admin is unaffected:
// Block anonymous access to the users endpoints, keep them
// working for logged-in users (wp-admin needs /wp/v2/users/me).
add_filter( 'rest_authentication_errors', function ( $result ) {
if ( true === $result || is_wp_error( $result ) ) {
return $result; // another check already decided
}
if ( ! is_user_logged_in() ) {
$route = $GLOBALS['wp']->query_vars['rest_route'] ?? '';
if ( preg_match( '#^/wp/v2/users\b#', $route ) ) {
return new WP_Error(
'rest_cannot_access',
'Authentication required.',
array( 'status' => 401 )
);
}
}
return $result;
} );
After removing or replacing the snippet, reload Site Health: the REST warning should clear immediately (no cache flush needed, but a hard reload with Ctrl+Shift+R helps).
Other causes worth checking
- Maintenance or coming-soon plugins: they intercept unauthenticated requests, which makes loopback tests fail while the site “works” for you as a logged-in admin.
- Password protection on the site or on wp-admin (HTTP Basic Auth): loopback requests do not carry the password, so they fail.
WP_HTTP_BLOCK_EXTERNALinwp-config.php: if defined withoutWP_ACCESSIBLE_HOSTSincluding your own domain, WordPress blocks its own loopback requests.- A plugin that changed the REST API prefix or disabled it for non-logged-in users globally.
About 400 errors on admin-ajax.php
Access logs and the Network tab sometimes show POST /wp-admin/admin-ajax.php returning 400 with a one-byte body (0). This is WordPress’s normal answer when the request has a missing or unregistered action parameter, typically from a half-loaded page or a plugin that was just deactivated. It comes from WordPress itself, not from a firewall, and single occurrences are harmless.
Still stuck?
If the external curl test passes but you cannot find the culprit, open a support ticket with the failing URL and status code from the Network tab. We can check the server logs and pinpoint which filter or plugin is intercepting the request.