AI brokers are now not experiments. They’re manufacturing infrastructure, making billions of HTTP requests per day, navigating the online, calling APIs, and orchestrating advanced workflows.
However when these brokers hit an error, they nonetheless obtain the identical HTML error pages we constructed for browsers: a whole bunch of traces of markup, CSS, and duplicate designed for human eyes. These pages give brokers clues, not directions, and waste time and tokens. That hole is the chance to present brokers directions, not obstacles.
Beginning at the moment, Cloudflare returns RFC 9457-compliant structured Markdown and JSON error payloads to AI brokers, changing heavyweight HTML pages with machine-readable directions.
Meaning when an agent sends Settle for: textual content/markdown, Settle for: software/json, or Settle for: software/downside+json and encounters a Cloudflare error, we return one semantic contract in a structured format as an alternative of HTML. And it comes full with actionable steering. (This builds on our latest Markdown for Brokers launch.)
So as an alternative of being informed solely “You were blocked,” the agent will learn: “You were rate-limited — wait 30 seconds and retry with exponential backoff.” As an alternative of simply “Access denied,” the agent will probably be instructed: “This block is intentional: do not retry, contact the site owner.”
These responses are usually not simply clearer — they’re dramatically extra environment friendly. Structured error responses minimize payload dimension and token utilization by greater than 98% versus HTML, measured in opposition to a reside 1015 (‘rate-limit’) error response. For brokers that hit a number of errors in a workflow, the financial savings compound rapidly.
That is reside throughout the Cloudflare community, mechanically. Web site house owners don’t have to configure something. Browsers preserve getting the identical HTML expertise as earlier than.
These are usually not simply error pages. They’re directions for the agentic internet.
When an agent receives a Cloudflare-generated error, it often means Cloudflare is imposing buyer coverage or returning a platform response on the shopper’s behalf — not that Cloudflare is down. These responses are triggered when a request can’t be served as-is, equivalent to invalid host or DNS routing, customer-defined entry controls (WAF, geo, ASN, or bot guidelines), or edge-enforced limits like fee limiting. In brief, Cloudflare is performing because the buyer’s routing and safety layer, and the response explains why the request was blocked or couldn’t proceed.
At the moment, these responses are rendered as HTML designed for people:
Entry denied | instance.com used Cloudflare to limit entry
To an agent, that is rubbish. It can not decide what error occurred, why it was blocked, or whether or not retrying will assist. Even when it parses the HTML, the content material describes the error however does not inform the agent — or the human, for that matter — what to do subsequent.
Should you’re an agent developer and also you needed to deal with Cloudflare errors gracefully, your choices had been restricted. For Cloudflare-generated errors, structured responses existed solely in configuration-dependent paths, not as a constant default for brokers.
Customized Error Guidelines can customise many Cloudflare errors, together with some 1xxx instances. However they rely upon per-site configuration, so they can not function a common agent contract throughout the online. Cloudflare sits in entrance of the request path. Meaning we will outline a default machine response: retry or cease, wait and again off, escalate or reroute. Error pages cease being ornament and grow to be execution directions.
Cloudflare now returns RFC 9457-compliant structured responses for all 1xxx-class error paths — Cloudflare’s platform error codes for edge-side failures like DNS decision points, entry denials, and fee limits. Each codecs are reside: Settle for: textual content/markdown returns Markdown, Settle for: software/json returns JSON, and Settle for: software/downside+json returns JSON with the software/downside+json content material kind.
This covers all 1xxx-class errors at the moment. The identical contract will prolong to Cloudflare-generated 4xx and 5xx errors subsequent.
Markdown responses have two components:
JSON responses carry the identical fields as a flat object.
The YAML frontmatter is the vital layer for automation. It lets an agent extract steady keys with out scraping HTML or guessing intent from copy. Fields like error_code, error_name, and error_category let the agent classify the failure. retryable and retry_after drive backoff logic. owner_action_required tells the agent whether or not to maintain attempting or escalate. ray_id, timestamp, and zone make logs and help handoffs deterministic.
The schema is steady by design, so brokers can implement sturdy management circulate with out chasing presentation modifications.
That stability just isn’t a Cloudflare invention. RFC 9457 — Drawback Particulars for HTTP APIs defines a typical JSON form for reporting errors over HTTP, so purchasers can parse error responses with out realizing the particular API upfront. Our JSON responses comply with this form, which implies any HTTP consumer that understands Drawback Particulars can parse the bottom members with out Cloudflare-specific code:
RFC 9457 member | What it accommodates |
| A URI pointing to Cloudflare’s documentation for the particular error code |
| The HTTP standing code (matching the precise response standing) |
| A brief, human-readable abstract of the issue |
| A human-readable clarification particular to this prevalence |
| The Ray ID figuring out this particular error prevalence |
The operational fields — error_code, error_category, retryable, retry_after, owner_action_required, and extra — are RFC 9457 extension members. Purchasers that do not acknowledge them merely ignore them.
That is network-wide and additive. Web site house owners don’t have to configure something. Browsers preserve receiving HTML until purchasers explicitly ask for Markdown or JSON.
What the response appears like
Here’s what a rate-limit error (1015) appears like in JSON:
{
"type": "
"title": "Error 1015: You are being rate limited",
"status": 429,
"detail": "You are being rate-limited by the website owner's configuration.",
"instance": "9d99a4434fz2d168",
"error_code": 1015,
"error_name": "rate_limited",
"error_category": "rate_limit",
"ray_id": "9d99a4434fz2d168",
"timestamp": "2026-03-09T11:11:55Z",
"zone": "",
"cloudflare_error": true,
"retryable": true,
"retry_after": 30,
"owner_action_required": false,
"what_you_should_do": "**Wait and retry.** This block is transient. Wait at least 30 seconds, then retry with exponential backoff.nnRecommended approach:n1. Wait 30 seconds before your next requestn2. If rate-limited again, double the wait time (60s, 120s, etc.)n3. If rate-limiting persists after 5 retries, stop and reassess your request pattern",
"footer": "This error was generated by Cloudflare on behalf of the website owner."
} The identical error in Markdown, optimized for model-first workflows:
---
error_code: 1015
error_name: rate_limited
error_category: rate_limit
standing: 429
ray_id: 9d99a39dc992d168
timestamp: 2026-03-09T11:11:28Z
zone:
cloudflare_error: true
retryable: true
retry_after: 30
owner_action_required: false
---
# Error 1015: You're being fee restricted
## What Occurred
You're being rate-limited by the web site proprietor's configuration.
## What You Ought to Do
**Wait and retry.** This block is transient. Wait at the least 30 seconds, then retry with exponential backoff.
Really helpful strategy:
1. Wait 30 seconds earlier than your subsequent request
2. If rate-limited once more, double the wait time (60s, 120s, and so forth.)
3. If rate-limiting persists after 5 retries, cease and reassess your request sample
---
This error was generated by Cloudflare on behalf of the web site proprietor.
Each codecs give an agent every part it must resolve and act: classify the error, select retry habits, and decide whether or not escalation is required. That is what a default machine contract appears like — not per-site configuration, however network-wide habits. The distinction is specific throughout error households: a transient error like 1015 says wait and retry, whereas intentional blocks like 1020 or geographic restrictions like 1009 inform the agent to not retry and to escalate as an alternative.
One contract, two codecs
The core worth just isn’t format selection. It’s semantic stability.
Brokers want deterministic solutions to operational questions: retry or not, how lengthy to attend, and whether or not to escalate. Cloudflare exposes one coverage contract throughout two wire codecs. Whether or not a consumer consumes Markdown or JSON, the operational that means is an identical: similar error identification, similar retry/backoff alerts, similar escalation steering.
Purchasers that ship Settle for: software/downside+json get software/downside+json; charset=utf-8 again — helpful for HTTP consumer libraries that dispatch on media kind. Purchasers that ship Settle for: software/json get software/json; charset=utf-8 — similar physique, secure default for present shoppers.
Measurement discount and token effectivity
That contract can be dramatically smaller than what it replaces. Cloudflare HTML error pages are browser-oriented and heavy, whereas structured responses are compact by design.
Measured comparability for 1015:
Payload | Bytes | Tokens (cl100k_base) | Measurement vs HTML | Token vs HTML |
HTML response | 46,645 | 14,252 | — | — |
Markdown response | 798 | 221 | 58.5x much less | 64.5x much less |
JSON response | 970 | 256 | 48.1x much less | 55.7x much less |
Each structured codecs ship a ~98% discount in dimension and tokens versus HTML. For brokers, dimension interprets instantly into token price — when an agent hits a number of errors in a single run, these financial savings compound into decrease mannequin spend and sooner restoration loops.
Ten classes, clear actions
Each 1xxx error is mapped to an error_category. That turns error dealing with into routing logic as an alternative of brittle per-page parsing.
Class | What it means | What the agent ought to do |
| Intentional block: IP, ASN, geo, firewall rule | Don’t retry. Contact website proprietor if sudden. |
| Request fee exceeded | Again off. Retry after retry_after seconds. |
| DNS decision failure on the origin | Don’t retry. Report back to website proprietor. |
| Configuration error: CNAME, tunnel, host routing | Don’t retry (often). Report back to website proprietor. |
| TLS model or cipher mismatch | Repair TLS consumer settings. Don’t retry as-is. |
| DMCA or regulatory block | Don’t retry. This can be a authorized restriction. |
| Cloudflare Staff runtime error | Don’t retry. Web site proprietor should repair the script. |
| Invalid URL rewrite output | Don’t retry. Web site proprietor should repair the rule. |
| Cloudflare Snippets error | Don’t retry. Web site proprietor should repair Snippets config. |
| Unsupported methodology or deprecated function | Change the request. Don’t retry as-is. |
Two fields make this operationally helpful for brokers:
You possibly can substitute brittle “if status == 429 then maybe retry” heuristics with specific management circulate. Parse the frontmatter as soon as, then department on steady fields. A easy sample is:
if
retryableistrue, waitretry_afterand retryif
owner_action_requiredistrue, cease and escalatein any other case, fail quick with out hammering the location
Here’s a minimal Python instance utilizing that sample:
import time
import yaml
def parse_frontmatter(markdown_text: str) -> dict:
# Expects: ---nn---n
if not markdown_text.startswith("---n"):
return {}
_, yaml_block, _ = markdown_text.break up("---n", 2)
return yaml.safe_load(yaml_block) or {}
def handle_cloudflare_error(markdown_text: str) -> str:
meta = parse_frontmatter(markdown_text)
if not meta.get("cloudflare_error"):
return "not_cloudflare_error"
if meta.get("retryable"):
wait_seconds = int(meta.get("retry_after", 30))
time.sleep(wait_seconds)
return f"retry_after_{wait_seconds}s"
if meta.get("owner_action_required"):
return f"escalate_owner_error_{meta.get('error_code')}"
return "do_not_retry" That is the important thing shift: brokers are now not inferring intent from HTML copy. They’re executing specific coverage from structured fields.
Ship Settle for: textual content/markdown, Settle for: software/json, or Settle for: software/downside+json.
For fast testing, you may hit any Cloudflare-proxied area instantly at /cdn-cgi/error/1015 (or substitute 1015 with one other 1xxx code).
curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015"
Instance with one other error code:
curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1020"
JSON instance:
curl -s --compressed -H "Accept: application/json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015" | jq .
RFC 9457 Drawback Particulars instance:
curl -s --compressed -H "Accept: application/problem+json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015" | jq .
The habits is deterministic — the primary specific structured kind wins:
Settle for header | Response |
| JSON |
| JSON |
| JSON (software/downside+json content material kind) |
| JSON |
| JSON (equal q, first-listed wins) |
| Markdown |
| Markdown (equal q, first-listed wins) |
| Markdown |
| Markdown |
| HTML (default) |
Wildcard-only requests (*/*) don’t sign a structured choice; purchasers should explicitly request Markdown or JSON.
If the request succeeds, you get regular origin content material. The header solely impacts Cloudflare-generated error responses.
There are a selection of conditions the place structured error responses assist instantly:
Agent blocked by WAF rule (
1020). The agent parseserror_code, dataray_id, and stops retrying. It might escalate with helpful context as an alternative of looping.MCP (Mannequin Context Protocol) instrument hitting geo restriction (
1009). The instrument will get a transparent, machine-readable motive, returns it to the orchestrator, and the workflow can select an alternate path or notify the consumer.Price-limited crawler (
1015). The agent readsretryable: true andretry_after, applies backoff, and retries predictably as an alternative of hammering the endpoint.Developer debugging with
curl. The developer can reproduce precisely what the agent sees, together with frontmatter and steering, with out reverse-engineering HTML.HTTP consumer libraries that perceive RFC 9457. Any consumer that dispatches on
software/downside+jsonor parses Drawback Particulars objects can deal with Cloudflare errors with out Cloudflare-specific code.
In every case, the result is identical: much less guessing, fewer wasted retries, decrease mannequin price, and sooner restoration.
Ship a structured Settle for header and take a look at in opposition to any Cloudflare-proxied area:
curl -s --compressed -H "Accept: text/markdown" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015"
curl -s --compressed -H "Accept: application/json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015" | jq .
curl -s --compressed -H "Accept: application/problem+json" -A "TestAgent/1.0" -H "Accept-Encoding: gzip, deflate" "/cdn-cgi/error/1015" | jq .
Error pages are the primary dialog between Cloudflare and an agent. This launch makes that dialog structured, standards-compliant, and low-cost to course of.
To make this work throughout the online, agent runtimes ought to default to specific structured Settle for headers, not naked */*. Use Settle for: textual content/markdown, */* for model-first workflows and Settle for: software/json, */* for typed management circulate. Should you keep an agent framework, SDK, or browser automation stack, ship this default and deal with naked */* as legacy fallback.
And it is just the primary layer. We’re constructing the remainder of the agent stack on high of it: AI Gateway for routing, controls, and observability; Staff AI for inference; and the identification, safety, and entry primitives brokers might want to function safely at Web scale.
Cloudflare helps our clients ship content material in agent-friendly methods, and that is simply the beginning. Should you’re constructing or working brokers, begin at brokers.cloudflare.com.



