WordPress loopback requests support scheduled events, editor checks, and background processing. A 401 usually points to an authentication challenge, while a 403 points to an authorization or security decision. The same site can return 200 in a logged-in browser and still deny the server's own request.
Use this when Site Health reports a failed loopback and the response is 401 or 403, especially on sites behind Basic Auth, a WAF, a maintenance gate, a security plugin, SSO, or a private staging rule.
Quick answer
Reproduce the request from the server without browser cookies, capture response headers and body, and test each access layer in order: DNS and TLS, CDN or WAF, host Basic Auth, maintenance rule, security plugin, and WordPress permissions. Add the narrowest server-to-self exception that preserves the intended public boundary.
What to check first
- Capture the Site Health message, target URL, status code, response headers, response body signature, request timestamp, resolved IP, Host header, and WordPress home and site URLs.
- Run the request from the web server or container with no cookies, then compare a browser, WP-CLI, PHP wp_remote_get, and external curl result.
- Identify WWW-Authenticate, CDN request IDs, WAF rule IDs, host challenge pages, maintenance cookies, security-plugin blocks, and login redirects.
- Temporarily allow only the exact loopback path or trusted origin on staging, then rerun Site Health and the background job that depends on it.
- Confirm the exception cannot expose wp-admin, private staging content, REST write routes, or authenticated data to an external unauthenticated client.
Diagnostic table
Use this table to keep the work practical. It connects the symptom to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Capture the denial fingerprint | Capture the Site Health message, target URL, status code, response headers, response body signature, request timestamp, resolved IP, Host header, and WordPress home and site URLs. | Site Health and wp cron test pass from the real server context. |
| Compare request contexts | Run the request from the web server or container with no cookies, then compare a browser, WP-CLI, PHP wp_remote_get, and external curl result. | The dependent scheduled or background task runs and records its completion. |
| Name the blocking layer | Identify WWW-Authenticate, CDN request IDs, WAF rule IDs, host challenge pages, maintenance cookies, security-plugin blocks, and login redirects. | External unauthenticated clients still cannot access protected routes or staging content. |
| Add a narrow exception | Temporarily allow only the exact loopback path or trusted origin on staging, then rerun Site Health and the background job that depends on it. | WAF, host, and WordPress logs show the allowed loopback and no unexplained broader bypass. |
Why this usually happens
- A logged-in browser carries cookies that the server-side loopback does not have.
- Basic Auth can protect staging before WordPress executes.
- WAF and bot rules can distrust a request whose source and destination share the same public address.
- A broad allowlist can fix Site Health while accidentally weakening the protection it bypasses.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
wp eval '$r=wp_remote_get(home_url("/wp-cron.php?doing_wp_cron=1")); print_r([wp_remote_retrieve_response_code($r), wp_remote_retrieve_headers($r)]);'
curl -sS -D - -o /tmp/loopback-body.txt https://example.test/wp-cron.php?doing_wp_cron=1
wp option get home
wp option get siteurl
wp cron test
Safe fix order
Do the work in a sequence that makes each result easy to prove. Stop if a step produces new evidence that changes the incident scope.
- Capture the denial fingerprint
- Compare request contexts
- Name the blocking layer
- Add a narrow exception
- Retest security boundaries
Decision rule
Fix the layer that produced the denial. Prefer an exact path, method, source, or signed-request exception over disabling Basic Auth, WAF, or the security plugin globally.
What to tell the client or owner
Share the Site Health output, target URL, status, denial headers and body fingerprint, resolved IP, request-context comparison, blocking rule, exception scope, dependent job result, and negative access test.
Production verification checklist
- Site Health and wp cron test pass from the real server context.
- The dependent scheduled or background task runs and records its completion.
- External unauthenticated clients still cannot access protected routes or staging content.
- WAF, host, and WordPress logs show the allowed loopback and no unexplained broader bypass.
Mistakes to avoid
- Do not add browser cookies or an administrator password to an automated loopback fix.
- Do not allowlist every request from the server's public IP without considering shared infrastructure.
- Do not disable the WAF globally to clear one status code.
- Do not stop after Site Health turns green without running the dependent job.
Questions teams ask during testing
Why does the homepage work while loopback fails?
The homepage may be cached or public, while wp-cron.php, REST routes, or admin-ajax.php cross a different WAF, Basic Auth, or security-plugin rule.
Can I ignore a loopback warning on staging?
Only if no required update, cron, editor, or background workflow depends on it and the team documents that choice. A private staging gate still needs a controlled maintenance path.
When HandL WP should help
HandL WP can trace loopback failures across DNS, TLS, CDN, WAF, Basic Auth, security plugins, WordPress HTTP requests, and cron without opening private routes broadly.
If this is active on a production site, fix WordPress loopback authentication.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references