A customer emails to say your shop "won't let them in". They saw a Cloudflare page with a four-digit code, gave up, and bought somewhere else. Your server logs show nothing, because the request never got past Cloudflare. This happens on WooCommerce stores, WordPress lead-gen sites, headless frontends on Astro or Next.js and any custom app proxied through Cloudflare. The cause is almost always a rule on your own zone, and Cloudflare records which one.
This guide walks through the order that works: get the Ray ID, look it up, read which feature acted, then narrow that feature so it stops catching buyers and payment callbacks. Every behaviour described below comes from Cloudflare’s developer documentation as of October 2026.
What Cloudflare error 1015, 1020 and 1009 mean
The code tells you where to look. A post in r/CloudFlare on 21 October 2026 summed up the codes, and each one matches Cloudflare’s own troubleshooting pages:
- 1015 (HTTP 429): a rate limiting rule matched. Cloudflare’s advice is to review thresholds and, if a rule counts over a very short period such as one second, try 10 seconds.
- 1020 (HTTP 403): a security rule with a Block action and no custom response. The 1020 page names API Shield schema validation and JWT validation as examples, and states that WAF custom rules and managed rules no longer return 1020. They serve the WAF block page instead.
- 1009 (HTTP 403): a country or region ban set in IP Access rules. Country blocks there are Enterprise-only; on other plans a country block is a custom rule, and that shows the WAF block page.
- 1010 (HTTP 403): Browser Integrity Check rejected the browser signature.
- “Just a moment…” or a challenge page: a Managed Challenge from a custom rule, a rate limiting rule, Bot Fight Mode or Under Attack Mode.
The 1020 detail saves hours. If you are combing through custom rules looking for the one that returned 1020, you are in the wrong list.
How to find the Cloudflare Ray ID
Ask the customer for a screenshot of the whole error page. It carries the code, the Ray ID and a UTC timestamp. The OP of the same thread added this in a reply:
the code’s the easy part, the bit people miss is the ray id on the same screen. paste it into security events and it shows which of your own rules fired.
(u/Hot_Bee_5451, r/CloudFlare, 22 October 2026)
A Ray ID is attached to every request through Cloudflare and sent to your origin in the cf-ray header. Cloudflare warns that Ray IDs are not guaranteed unique, so match the timestamp and IP as well. If the customer cannot send a screenshot, ask for their public IP address and the approximate time and country. For challenge failures there is a second route, suggested in another thread:
Well you can provide the RayID that is created when it runs that test to the website admin and they can look up the exact reason you failed.
(u/Logvin, r/CloudFlare, 21 October 2026)
How to search a Ray ID in Cloudflare Security Events
In the dashboard, open Security > Analytics and the Events tab. Add a filter for Ray ID, or for the client IP, and set the time range to cover the complaint. Convert the UTC time from the error page to your own timezone first; Cloudflare’s 1020 page points this out explicitly.
Two limits from the Security Events documentation matter here. Data is kept for up to 31 days. And the list uses sampled logs, so on a busy zone a single request may not appear. If the Ray ID search returns nothing, narrow the time window to a few minutes and filter by IP; a smaller window shows more events. One request can also produce several events if several features acted on it.
Which Cloudflare rule blocked the visitor
Expand the event. The Service field names the feature, and for rules you also get the rule name or ID. What each one usually means:
- Custom rules: your own expression. Common culprits are country blocks, ASN blocks aimed at hosting providers (which also catch VPN users) and over-broad path rules on
/wp-login.phpor/checkout. - Managed rules: a Cloudflare or OWASP signature matched something in the request. Long search queries, form fields containing code snippets and some page-builder payloads trip these.
- Rate limiting rules: the 1015 case. Shoppers behind one office or mobile carrier IP share a counter when the rule counts by IP.
- Bot Fight Mode or Super Bot Fight Mode: the bot products. Cloudflare’s bot documentation says both may challenge API or mobile app traffic.
- Security Level or Under Attack Mode: the zone-wide interstitial.
A deleted rule shows as “Rule unavailable”. Check the audit log to see who removed or changed it.
How to create a Cloudflare skip rule without opening the whole site
The fix is a custom rule with the Skip action, placed above the rule that blocked, matching only the traffic you trust. Cloudflare’s skip options let you skip all remaining custom rules, all rate limiting rules, all managed rules and all Super Bot Fight Mode rules. Through the API you can also skip Browser Integrity Check, Security Level, User Agent Blocking, Zone Lockdown and Hotlink Protection. Custom rules run in order, so position matters.
Keep the expression narrow. For the WooCommerce Stripe extension, which uses only /?wc-api=wc_stripe as its webhook endpoint:
(http.request.uri.query contains "wc-api=wc_stripe" and ip.src in $stripe_webhooks)Here $stripe_webhooks is an IP list you create from Stripe’s published webhook IP addresses. For a store integration calling the WooCommerce REST API from a fixed server:
(starts_with(http.request.uri.path, "/wp-json/wc/") and ip.src in $erp_servers)For a false positive that hit real shoppers, often the better fix is to change the original rule instead of adding an exception: raise the rate limit period, scope a country block to /wp-login.php, or switch a Block to a Managed Challenge. Leave Log matching requests on for the skip rule so you can see it working.
Can a WAF rule bypass Bot Fight Mode
No. The Bot Fight Mode page says you cannot bypass or skip it with WAF custom rules or Page Rules, because it does not run on the Ruleset Engine, so Skip, Bypass and Allow have no effect. The skip options page repeats that only Super Bot Fight Mode can be skipped. One exception is documented: Bot Fight Mode does not trigger if an IP Access rule matches the request first.
So on the Free plan, if Bot Fight Mode challenges your payment provider, your ERP or your uptime monitor, you have three choices: an IP Access allow rule for that provider’s addresses, turning Bot Fight Mode off, or moving to a paid plan where Super Bot Fight Mode accepts skip rules. Super Bot Fight Mode also has an Optimize for WordPress setting that lets WordPress loopback requests through, which fixes Site Health errors without a custom rule.
Why Cloudflare blocks Stripe webhooks and WooCommerce REST API calls
Server-to-server calls have no browser, so they cannot solve a JavaScript challenge. Any feature that challenges instead of blocking still breaks them. A store owner described exactly this in r/CloudFlare:
When I turn on Under Attack Mode, the Singapore traffic stops in GA4. But Under Attack Mode makes my site slow, and my server-to-server API calls (WooCommerce REST API) get the Cloudflare “Just a moment…” challenge, so they fail.
(u/lastoneinbatumi, r/CloudFlare, 19 October 2026)
The cost differs by provider. Stripe retries a failed webhook with exponential backoff for up to three days in live mode, so orders stuck as “pending payment” usually recover once you fix the rule. Shopify retries up to eight times over four hours and then removes the subscription, which matters if your app or headless backend receives Shopify webhooks behind your Cloudflare zone. Check each provider’s dashboard for failed deliveries after any security change.
Under Attack Mode is meant as a last resort during an attack. Cloudflare’s Security Level page says to use a configuration rule to turn it on or off for your API or any other part of the domain. Keep it off for /wp-json/, webhook paths and your API host.
The same thread had a second lesson. When blocked traffic keeps appearing in analytics, ask whether it goes through Cloudflare at all:
Is your host configured to only allow traffic to and from Cloudflare? Otherwise it could be reached directly by ip
(u/Wilbo007, r/CloudFlare, 19 October 2026)
Cloudflare’s IP address documentation recommends blocking traffic at the origin that does not come from Cloudflare or your trusted partners. Allow your payment providers’ addresses in that origin firewall too.
Cloudflare block troubleshooting table
| What the customer or log shows | Likely rule | Fix |
|---|---|---|
| Error 1015, HTTP 429 | Rate limiting rule | Longer counting period, higher threshold, or skip rate limiting for trusted IPs |
| WAF block page, HTTP 403, no 1xxx code | WAF custom rule or managed rule | Find the rule by Ray ID; narrow the expression or add a skip rule above it |
| Error 1020, HTTP 403 | Another Block without custom response (for example API Shield) | Look in Security Events, not in custom rules |
| Error 1009 | Country block in IP Access rules | Allow the visitor’s IP or move geoblocking to a scoped custom rule |
| Error 1010 | Browser Integrity Check | Skip it for the affected path via API, or turn it off |
| Challenge loop on every page | Under Attack Mode or Security Level | Turn it off, or limit it with a configuration rule |
| Webhook or REST API failing, no human involved | Bot Fight Mode, Under Attack Mode or a challenge rule | IP Access allow or Super Bot Fight Mode skip rule; keep UAM off API paths |
| Nothing in Security Events | Sampling, wrong time zone, or the request never reached Cloudflare | Smaller time window, filter by IP; check DNS and the origin firewall |
How to monitor Cloudflare blocks after the fix
Do not stop at one customer. In Security Events, filter by Action equal to Block or Managed Challenge and group by path. Requests to /checkout, /cart, /my-account, /wp-json/ or your contact form endpoint are the ones costing money. The filtered URL can be shared, so a colleague sees the same view. Up to 500 sampled events can be exported as JSON.
Then check the other side: failed deliveries in Stripe, PayPal or Shopify, WooCommerce orders stuck in pending, and contact form submissions per day. A drop the day after a security change points straight at the rule you added. Our Cloudflare edge service covers rule audits of this kind, and the store reliability plan includes this monitoring for WooCommerce shops.
Related reading: whether Cloudflare’s AI bot settings also stop search crawlers is covered in does Cloudflare block Googlebot. How much of a small site’s traffic is automated, and why that tempts owners into aggressive bot rules, is in 72% of our traffic is not a browser. For moving logic to the edge, see Cloudflare Workers and WooCommerce.







