CORS errors when Hubbee can't reach your site
CORS errors when Hubbee can’t reach your site
Hubbee’s calls to WordPress are server-to-server. Strictly speaking they shouldn’t be subject to browser CORS rules — they aren’t browser requests. But several common setups insert a CORS-aware middleware that rejects the call anyway, and the resulting symptom looks like a CORS error in our diagnostic.
How to recognise the problem
The diagnostic reports cors_blocked. The response body or headers contain phrases like:
Access-Control-Allow-Originnot allowed by Access-Control-Allow-OriginCORS policy: No 'Access-Control-Allow-Origin' header is present
If you open the WP browser DevTools → Network and the OPTIONS preflight to /wp-json/bz/v1/* returns 403 or 405, you have a CORS issue.
Root causes (in order of likelihood)
1. Cloudflare Workers transforming responses. Some account-level Workers strip or rewrite REST API headers, breaking the dialect Hubbee expects. Disable any Worker bound to /wp-json/* and retry.
2. WordPress security plugin replacing the REST Server. Wordfence, Sucuri, and iThemes can substitute their own REST handler. See Firewall and security plugin conflicts.
3. Custom rest_pre_serve_request filter. A theme or custom plugin can override the REST response and forget to emit the right headers. Find it:
grep -r "rest_pre_serve_request" wp-content/plugins/ wp-content/themes/
If you find a customisation, the fix is to either remove it or extend it to allow */wp-json/bz/v1/* paths through unchanged.
4. Hard-coded Access-Control-Allow-Origin in .htaccess / nginx.conf. Some “hardening” guides recommend pinning the header to a single origin. That breaks server-to-server clients like Hubbee. Remove or scope the rule:
# Bad — blocks Hubbee
Header set Access-Control-Allow-Origin "https://your-site.com"
# Better — scope to browser-facing JS only
<LocationMatch "^/wp-json/wp/v2">
Header set Access-Control-Allow-Origin "https://your-site.com"
</LocationMatch>
5. Reverse proxy stripping the Authorization header. Some reverse proxies (especially homegrown nginx setups) strip the Authorization header before passing to WordPress. Hubbee uses Bearer tokens — without the header, WordPress returns 401, the diagnostic falls back to the closest match (often cors_blocked when an OPTIONS preflight also fails). Verify with:
curl -i -H "Authorization: Bearer test" https://your-site.com/wp-json/bz/v1/ping
# Expect: 401 with body { "code": "bz_unauthorized" }
# If you get: 401 with body { "code": "missing_authorization" }, the header is being stripped
Nginx fix:
location / {
proxy_set_header Authorization $http_authorization;
proxy_pass http://php-fpm;
}
Quick test: bypass and confirm
Temporarily disable each layer one at a time:
- Cloudflare → enable Development Mode for 3 hours (skips most rules, useful for testing)
- WordPress → deactivate all security plugins
- Hosting → bypass any reverse-proxy-level WAF (Sucuri, host-managed WAFs)
After each step, Site → Run diagnostic. The first one that flips cors_blocked to null is your culprit. Re-enable layers and tune them per the sections above.
Why the diagnostic sometimes reports CORS when the real cause is something else
Our diagnose-site Edge Function pattern-matches the response body. When the body contains the word “CORS” — even just in a debug log line emitted by a security plugin — we surface it as cors_blocked. If the suggested fix from the diagnostic doesn’t match the symptoms, check the Probe details dropdown below the result: it shows the raw HTTP status and response snippet so you can spot the actual cause.
Was this article helpful?
Related articles
Still stuck?
Open a support thread and we'll get back to you. Most replies arrive within a few hours on business days.
