A customer emails you a screenshot: a plain orange-and-white Cloudflare page reading "Error 1020 Ray ID: ... Access denied" instead of your site. No 500, no timeout, nothing in your server's error log — because the request never even reached your server. Cloudflare stopped it at the edge, and it's telling you exactly why: something in your own Cloudflare configuration blocked that visitor.
What Error 1020 Actually Means
Error 1020 is Cloudflare's way of saying "a firewall rule you configured matched this request, and the action was Block." It's different from the 5xx-range Cloudflare errors (520, 521, 522, and friends), which mean Cloudflare couldn't reach your origin server. 1020 means Cloudflare reached a decision on its own, before your server was ever involved.
That distinction matters for troubleshooting. If you're seeing 1020, don't waste time checking PHP-FPM, Apache, or MySQL — your origin is fine. The problem lives entirely inside your Cloudflare dashboard.
Common Causes
- WAF custom rules — a rule under Security > WAF > Custom rules that matches on country, ASN, User Agent, URI path, or a combination, with the action set to Block.
- IP Access Rules — a specific IP, IP range, or country blocked under Security > WAF > Tools (or the legacy Firewall > Tools screen on older dashboards).
- Bot Fight Mode or Super Bot Fight Mode — overly aggressive bot scoring that flags a legitimate crawler, monitoring tool, or even a payment gateway's server-to-server callback as a bot.
- A managed ruleset exception gone wrong — someone enabled a rule from the Cloudflare Managed Ruleset with the action overridden to Block instead of the default Managed Challenge.
- Rate limiting rules misconfigured too aggressively — though this usually throws error 1015, not 1020, it's worth ruling out if the block is intermittent.
A quick way to tell which one it is
Every 1020 page shows a Ray ID at the bottom. Copy it, then go to Security > Events (or Security > WAF > Overview depending on your dashboard version) in the Cloudflare dashboard for that zone and search for the Ray ID. The event log tells you exactly which rule fired — the rule name, the service (Custom Rules, Bot Management, Managed Rules, IP Access Rules), and the matched criteria. This is the single most useful step; don't skip straight to guessing.
How to Fix It
1. Found it in a WAF Custom Rule
Go to Security > WAF > Custom rules, open the rule the event log pointed to, and check the expression. A rule written to block a specific country or ASN sometimes catches more than intended — for example, blocking (ip.geoip.country eq "XX") also blocks legitimate visitors, VPN users, and sometimes even your own office IP if you're routing through a VPN exit node in that country. Either narrow the expression (add an AND condition for a suspicious URI path or user agent) or change the action from Block to Managed Challenge so real users get a JS challenge instead of an outright wall.
2. Found it under IP Access Rules
Go to Security > WAF > Tools. Search the list for the blocked IP or country. If it was added deliberately (say, after a past attack) but is now blocking a legitimate office or a partner API, either delete the rule or change its scope from "this zone" to something narrower, or switch the action to Challenge.
3. Bot Fight Mode is the culprit
This is the most common cause for false positives on things like payment webhooks (Razorpay, Stripe, PayPal IPN), uptime monitors (UptimeRobot, Pingdom), and SEO crawlers. Go to Security > Bots and either turn Bot Fight Mode off for that zone, or if you're on a plan with Super Bot Fight Mode, add the offending service's known IP ranges or user agent to a WAF Custom Rule with a Skip action for "Bot Fight Mode" specifically, so it bypasses just that check instead of disabling bot protection site-wide.
4. A managed rule with an overridden action
Under Security > WAF > Managed rules, check if any individual rule inside the Cloudflare Managed Ruleset or OWASP Core Ruleset has its action overridden to Block. These are usually fine at the default (Managed Challenge or Log), and only get switched to a hard Block by someone tightening security after an incident. If a legitimate request is matching a rule pattern — a WordPress REST API call with a JSON body that looks like an SQLi pattern is a classic false positive — add an exception for that specific rule ID scoped to your site's own API paths, rather than disabling the whole ruleset.
| Symptom | Likely source | Where to look |
|---|---|---|
| Only visitors from one country blocked | Custom Rule or IP Access Rule with a country match | Security > WAF > Custom rules / Tools |
| Only a specific IP or office blocked | IP Access Rule | Security > WAF > Tools |
| Payment gateway webhook or API callback blocked | Bot Fight Mode / Super Bot Fight Mode | Security > Bots |
| Only certain URLs or POST requests blocked | Managed Ruleset with overridden action | Security > WAF > Managed rules |
| Blocked after a burst of traffic, self-resolves | Rate limiting rule (often shows 1015, not 1020) | Security > WAF > Rate limiting rules |
If You're Hosting With SkyServer Behind Cloudflare
None of this touches your cPanel or VPS configuration — 1020 is purely a Cloudflare dashboard setting. If you're not sure which of your team members has access to the Cloudflare account for the domain, that's usually step zero: log into dash.cloudflare.com, select the zone, and check Manage Account > Members to see who last touched the WAF rules. It's common for a rule added months ago during a bot attack to quietly start blocking real traffic once your visitor base changes.
Prevention
- Prefer Managed Challenge over Block for new WAF rules unless you're certain the traffic is entirely malicious. A challenge lets real humans through; a hard block doesn't discriminate.
- Whitelist known-good service IPs (payment gateways, monitoring tools, your own office) as a Skip rule before turning on Bot Fight Mode or tightening Custom Rules.
- Review Security > Events monthly, not just when someone complains — it shows you which rules are firing and how often, so you can catch an overly broad rule before it becomes a support ticket.
- Document why each Custom Rule exists (Cloudflare lets you name rules) so six months later someone doesn't have to guess whether it's safe to remove.
- Test new WAF rules in Log mode first, watch the Events tab for a day, then switch to Block once you've confirmed it's only catching what you intend.
Frequently Asked Questions
Is Error 1020 something wrong with my hosting or server?
No. Error 1020 happens entirely at Cloudflare's edge, before the request reaches your server. Your cPanel, VPS, or application is not involved and doesn't need any changes.
Why am I blocked but my colleague on the same network isn't?
Rules can match on more than just IP — user agent, browser fingerprint, ASN, or bot score can all differ between two devices on the same network, especially if one is using a VPN, extension, or outdated browser that trips a bot-detection signal.
Can I just turn off all WAF rules to stop this?
You can, but you shouldn't leave it that way. Disabling WAF protection entirely reopens the site to the exact traffic those rules were meant to catch. Fix the specific rule causing the false positive instead of switching everything off.
The Ray ID from the error page isn't showing up in my Events log. Why?
Event logging depth depends on your Cloudflare plan — Free and Pro plans retain firewall events for a shorter window than Business or Enterprise. If the block happened more than 24-72 hours ago (depending on plan), the event may have already rolled off. Ask the visitor to reproduce it and check the log within a few hours.
A specific country's users are blocked, but I never set that up. Where did it come from?
Check if Super Bot Fight Mode or a Managed Ruleset override is enabled — both can apply broader geographic or behavioral blocks than an explicit Custom Rule, and neither shows up as clearly under Custom rules. The Security Events log is still the fastest way to identify the actual source.
