Reference guide · cloudflare · Published 2026-08-16 · 4 min read
Cloudflare Transform Rules for headers
Use Cloudflare Transform Rules to set, add, or remove request and response headers at the edge without code. Free plan quota and Worker comparison included.
- ·What Transform Rules do
- ·Plan limits
- ·Header examples
What a Transform Rule does
Transform Rules edit the HTTP request or response while traffic crosses the Cloudflare edge, with no code on your origin or in a Worker. There are three families:
| Family | What it changes | Runs on |
|---|---|---|
| Request header modification | Set, add, or remove request headers sent to the origin | The outbound leg to your server |
| Response header modification | Set, add, or remove response headers sent to visitors | The inbound leg back to the browser |
| URL rewrite | Rewrite the path and query string before the origin sees it | The request path |
Each matching request or response runs against the rule set. The header operations are declarative: set overwrites, add keeps existing values, and remove deletes the header. Dynamic values can be pulled from request fields (for example the visitor country or cf-connecting-ip), so a rule can stamp X-Visitor-Country for every request without the origin doing any work.
Free plan limits (the ones that usually bite)
| Limit | Free | Pro | Business | Enterprise |
|---|---|---|---|---|
| Active Transform Rules | 10 | 25 | 50 | 300 |
| Regular expressions in rules | No | No | Yes | Yes |
- Free and Pro cannot use regex in the rule expression or in header values; Business and Enterprise can.
- The rule quota counts active rules across all three families for the zone.
- Response header transforms cannot modify headers whose name starts with
cf-orx-cf-, and cannot touch a small hard-coded list (server, and a few vendor-managed ones). This matters when you try to setcf-cache-statusmanually, which is not something a transform (or a Worker) should do; leave the cache-status signal to the edge itself. - Managed Transforms (pre-built header tools) count against the same quota as hand-authored rules.
When a job fits inside one or two rules, Transform Rules beat a Worker: no worker to deploy, no bundle to patch, no CPU budget to watch. The dashboard route also means someone who only has firewall/administrator access can add the rule without code review.
Header examples
Request header (set a forwarding header on the way to the origin):
if: http.host equals "www.example.com"
action: set X-Forwarded-Prefix /support
Response header (stamp a Content-Security-Policy for every page):
if: true
action: set Content-Security-Policy "default-src 'self'"
Response header, dynamic (add the visitor country):
if: true
action: add X-Visitor-Country {http.request.geo.country}
Header transforms are set at the zone level and cannot be scoped per environment until you add a matching hostname rule. If you need device-type caching, the same device-type header used for the cache key can be injected here rather than re-writing it in the app.
When not to use a Transform Rule
- Regex filtering on Free: you cannot turn on a "let non-[a-z] through" rule, so a Free site with complex path matching needs a Worker.
- Large or computed bodies: a header rule only edits headers, not the body. If the change is inside the payload, use a Worker or origin code.
- Per-request cache key logic: cache key assembly hooks into Cache Rules, not Transform Rules; put custom key decisions in a Cache Rule and let the transform stamp informational headers only.
- When the job belongs upstream: setting a header the origin would set itself is a second source of truth. Prefer the server for real config, and use the edge only for absence or debug helpers.
The comparison table
| Need | Transform Rule | Worker |
|---|---|---|
| Set/remove a few headers on matched traffic | Yes, smallest option | Overkill |
| Change the URL path or query | Yes (URL Rewrite family) | Yes |
| Inspect or alter the response body | No | Yes |
| Regex matching | Business and up | Always |
| Adds a request per match | No extra request | Runs per request |
The rule that decides which route to take is scope: headers on defined traffic, Transform Rules; anything that computes from the body, needs to be conditional in a way your plan can't express, or runs beyond the header layer, a Worker. The Workers basics guide shows the trade-off from the other side.