What Cloudflare’s 1xxx error codes actually mean
Cloudflare’s 1xxx error codes are Cloudflare’s own reason for refusing a request, written in the response body, while the HTTP status your monitor records is a separate number. Here is every code, the status it sends, and who has to fix it.A Cloudflare 1xxx error code is Cloudflare’s own explanation of why it refused or could not route a request, and it is not an HTTP status code. The number appears in the body of the error response. The status line carries a separate, ordinary HTTP code: 403, 409, 429, 500, 503 or 530. So "error 1020" and "403 Forbidden" are the same event seen from two places.
This matters most if you watch a site from the outside. An uptime monitor, a log pipeline or a load balancer health check usually records only the status. A 403 there could be a firewall rule you wrote, a country block, a DNS record pointing at the wrong address, or your own application refusing the request. The 1xxx code is what tells them apart, and a status-only check never sees it.
This is the second part of a series. The guide to Cloudflare’s 5xx error codes covers 520 through 526, the errors Cloudflare shows when it cannot get a usable answer from your server. The 1xxx family is mostly about what happens before your server is even asked.
What a 1xxx error looks like on the wire
Cloudflare’s 1xxx error reference says 1xxx errors "appear in the HTML body of the response". That is true for the error pages visitors usually screenshot, but not for every response. Here is a request sent straight to a Cloudflare IP address, with no hostname, captured on 20 October 2026:
curl -si http://104.16.132.229/HTTP/1.1 403 Forbidden
Content-Type: text/plain; charset=UTF-8
Content-Length: 17
Server: cloudflare
CF-RAY: a4dad4194c3066f2-AMS
error code: 1003The whole body is 17 bytes of plain text. Sending the same request with a browser User-Agent and Accept: text/html returned the same 17-byte text response, not an HTML page. Sending it with a Host header for a domain that is not on Cloudflare returned 409 Conflict with error code: 1001 in the body, in the same format.
Two things follow from this. A monitor that only stores the status recorded "403" and "409" here, and nothing that points to DNS or routing. And a monitor that looks for an HTML error page will not always find one. The reliable part is the short line error code: 1xxx in the body.
Every Cloudflare 1xxx error code and the status it sends
Cloudflare’s status table, last updated 14 October 2026, lists 33 codes. Grouped by who can actually fix them, they look like this. The status column comes directly from that table; the descriptions are condensed from each code’s own page.
| Code | What Cloudflare says happened | HTTP status | Who has to act |
|---|---|---|---|
| Blocked by the site’s own security settings | |||
| 1005 | Visitor’s network (ASN) is banned | 403 | Site owner |
| 1006, 1007, 1008, 1106 | Visitor’s IP address is banned | 403 | Site owner |
| 1009 | Visitor’s country or region is banned | 403 | Site owner |
| 1010 | Browser signature blocked (Browser Integrity Check) | 403 | Site owner |
| 1011 | Hotlink protection blocked the resource | 403 | Site owner |
| 1012 | Access denied over malicious activity from the visitor’s network | 403 | Visitor, then site owner |
| 1015 | Rate limited by the site’s rules | 429 | Visitor waits, or site owner adjusts the rule |
| 1020 | A security rule with a Block action matched | 403 | Site owner |
| The site’s DNS or Cloudflare setup is wrong | |||
| 1000 | DNS record points to a prohibited IP (often a Cloudflare IP) | 403 | Site owner |
| 1001 | DNS resolution error | 409 | Site owner |
| 1002 | DNS points to a prohibited IP, or a bad CNAME target | 403 | Site owner |
| 1004 | Host not configured to serve web traffic | 409 | Site owner, or Cloudflare support |
| 1014 | CNAME points into a different Cloudflare account | 403 | Site owner |
| 1016 | Origin DNS error: Cloudflare cannot resolve your origin | 530 | Site owner |
| 1034 | Edge IP restricted (record points at an IP you don’t control) | 403 | Site owner |
| Workers, tunnels and rewrite rules | |||
| 1019 | A Worker calls itself recursively | 503 | Developer |
| 1025 | Workers plan limits reached | 429 | Site owner |
| 1033 | Cloudflare Tunnel has no healthy cloudflared connection | 530 | Site owner |
| 1035, 1037, 1040, 1041 | Invalid request rewrite or rewrite rule | 500 | Site owner |
| 1036 | Rewrite exceeded the maximum length | 400 | Site owner |
| 1101 | Worker threw a JavaScript exception | 500 | Developer |
| 1102 | Worker exceeded its CPU or memory limit | 503 | Developer |
| The request itself, or Cloudflare’s edge | |||
| 1003 | Direct IP access to a Cloudflare address | 403 | Whoever sent the request |
| 1013 | HTTP hostname and TLS SNI hostname don’t match | 403 | Client or a proxy in between |
| 1018, 1023 | Could not find host (new zone or partner DNS failure) | 409 / 503 | Cloudflare support |
| 1200 | Too many requests queued for the origin | 503 | Site owner (origin capacity, cache hit rate) |
Most of the table is in the first two groups, and that is the useful split. If the code is in the first group, the request was blocked on purpose by a setting someone on the site owner’s side turned on, and a visitor can do almost nothing except ask. Cloudflare’s own pages say it repeatedly: Cloudflare support cannot override a customer’s security settings, and only the website owner can contact Cloudflare for technical support. If the code is in the second group, nobody blocked anything. The site is misconfigured, and every visitor gets the same error.
One code is missing from the table on purpose. Error 1104, "a variation of this email address is already taken", appears in Cloudflare’s list of 1xxx errors but has no status in the table. It is about Cloudflare accounts, not about visiting a website.
Error 530: one status, two unrelated problems
HTTP 530 is not in the 520 to 526 group, even though the numbers sit close together. Cloudflare’s error 530 page says it is returned when Cloudflare has trouble resolving the origin hostname, and that "the body of the response contains an 1XXX error code". In the status table, two codes map to 530:
- 1016, origin DNS error: the DNS record Cloudflare uses to find your server leads nowhere. Usually an A record is missing, or a CNAME points to an external name that no longer resolves, for example after moving hosts or letting a third-party hostname expire.
- 1033, Cloudflare Tunnel error: the hostname is served through Cloudflare Tunnel and Cloudflare cannot find a healthy cloudflared instance to send the traffic to. The machine running cloudflared may be off, the process may have crashed, or the DNS record may point at the wrong tunnel.
The fixes have nothing in common. 1016 is a DNS record to correct in the dashboard. 1033 is a process or a server to bring back. A monitor that alerts on "530" alone can send you to the wrong place, so read the body before you touch anything. For 1033, cloudflared tunnel list shows whether the tunnel is active; for 1016, look up the origin record’s target in any DNS tool and check that it returns an address.
Is that 403 from Cloudflare or from your server?
A 403 is the most common status in the table, and it is also what your own server returns when its application, a WordPress security plugin or an nginx deny rule refuses a request. When Cloudflare passes your server’s 403 along, the status line looks exactly like one Cloudflare generated itself.
Cloudflare does document a header that helps. Its error diagnostic headers page says that when Cloudflare generates an error page itself, the response includes cf-error-type and cf-error-origin, and that these headers "are present only on Cloudflare-generated error pages, not on errors forwarded from your origin server". The page lists 1000, 1016, 1101, 1102 and 52x as common values.
Our 1003 and 1001 captures above came back without cf-error-type. So the header is a good sign when it is present, but its absence does not prove the error came from your origin. The body is the better test: a Cloudflare-generated 1xxx response contains error code: 1 followed by the number, and your own application’s 403 page does not.
Cloudflare documents both in its error 1020 page and its notes on the different error page for blocked requests. If the request being blocked is your monitoring tool’s own check, that is a separate problem with its own fixes, covered in why Cloudflare can make your uptime monitor lie to you.
Workers errors 1101 and 1102 look like your own server failing
If your site runs a Cloudflare Worker in front of the origin, two more codes matter. 1101 means the Worker threw a JavaScript exception, and it is sent as a 500. 1102 means the Worker went over its CPU time or memory limit, and it is sent as a 503.
Both statuses are exactly what a crashed or overloaded origin returns. A status-only monitor that sees a run of 500s will send you to your application logs, and the logs will be clean, because the request never reached your server. The fix is in the Worker’s logs under Workers & Pages in the dashboard, or in wrangler tail while you reproduce the error. Cloudflare’s header page lists 1101 and 1102 as cf-error-type values, so this is the one case where checking that header first is worth it.
What a monitor needs to catch 1xxx errors
Our position: for a site behind Cloudflare, the status code is the wrong key to diagnose from. Cloudflare’s own status table exists, in its words, so you can find these errors "in logs, analytics, or monitoring that record only the HTTP status". That makes the gap clear. A status tells you which row of the table to start from, never which code you actually got.
Two settings close most of the gap:
- Expect the status your page really returns, usually 200, and treat anything else as a failure. Every 1xxx error arrives as a non-200 status, so this alone catches all of them. It doesn’t name them, though.
- Require a body keyword that only your real page contains, such as a phrase from your footer or a product name. A Cloudflare error page, plain text or HTML, will never contain it, so the check fails on any page that isn’t yours, even one that arrives with a status you chose to allow.
WebPixie’s uptime monitoring supports both: an expected status code and a body keyword per check. A status-code or keyword mismatch opens an incident on the first failed check, without the retry rounds used for network errors. That cuts both ways for 1015. If a rate-limiting rule on your site counts your monitor’s requests, the first 429 opens an incident. The fix is to exempt the monitor in the rule, not to slow the checks down until the alert stops.
When the alert fires, the first step is the same whatever the status: request the URL yourself with curl -si, read the body for an error code: line, and look the number up in the table above. That one line saves you a trip through the wrong set of logs.